﻿using HalconDotNet;
using Halcon二次开发.Controller.CamerForm交互;
using Halcon二次开发.Controller.主界面交互;
using Halcon二次开发.Controller.多模板匹配;
using Halcon二次开发.Controller.精准测量模块功能;
using Halcon二次开发.Model.储放所有单例.储存每个单例界面;
using Halcon二次开发.Tools;
using Halcon二次开发.View.中心距;
using Halcon二次开发.View.卡尺;
using Halcon二次开发.View.图片显示弹窗;
using Halcon二次开发.View.多模板匹配;
using Halcon二次开发.View.工位监控画面;
using Halcon二次开发.View.相机;
using Halcon二次开发.View.精准测量模块;
using halcon联合.自定义控件;
using Sunny.UI;
using System;
using System.Buffers;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web.UI.WebControls;
using System.Windows.Forms;
using System.Windows.Media.Animation;
using 可视化工具.View.Csv文件;
using Image = System.Drawing.Image;
using MouseEventArgs = System.Windows.Forms.MouseEventArgs;
using TreeNode = System.Windows.Forms.TreeNode;
using TreeNodeCollection = System.Windows.Forms.TreeNodeCollection;

namespace Halcon二次开发.Model.自定义控件
{
    public partial class HwindowFlowNodeUrseControl : UserControl
    {
        public CsvMainForm csvMainForm;
        public Dictionary<string, int> ngDictionary = new Dictionary<string, int>();
        //监控画面的窗口对象
        public FramesTimeForm framesTimeForm;
        /// <summary>
        ///  ok个数集合
        /// </summary>
        public int okCount = 0;
        /// <summary>
        /// ng个数集合
        /// </summary>
        public int ngCount = 0;
        /// <summary>
        /// 运行按钮点击次数 计数器
        /// </summary>
        int runCount = 0;
        /// <summary>
        /// 这个板块的所有小窗体
        /// </summary>
        public List<Form> forms = new List<Form>();
        //当前任务名字
        public string name;
        //当前工程名字
        public string projectName;
        /// <summary>
        /// 当前显示的图像(需要一直获取)
        /// </summary>
        public HObject hImage;

        public Form1Controller form1Controller;
        /// <summary>
        /// 图像索引
        /// </summary>
        public int count;

        /// <summary>
        /// 鼠标右击选择输入输出的子节点对象
        /// </summary>
        public TreeNode mouseNode;
        /// <summary>
        /// 鼠标出现在节点上方获取的节点对象
        /// </summary>
        public TreeNode msMoveNode;
        //当前工位相机对象
        public CamerFormController camerFormController;

        public HwindowFlowNodeUrseControl()
        {
            try
            {
                InitializeComponent();
                //取消线程之间的访问
                CheckForIllegalCrossThreadCalls = false;
                //给HSmart绑定缩放事件
                hSmartWindowControl1.MouseWheel += HSmartWindowControl1_MouseWheel;
                foreach (Image item in ((Form1)FormDb.Db["Form1"]).imageList1.Images)
                {
                    imageList1.Images.Add(item);
                }
                treeView1.SelectedImageIndex = 149;

                hSmartWindowControl1.HalconWindow.SetWindowParam("graphics_stack_max_element_num", 10000);
                runPaper = false;
                hSmartWindowControl1.SetFullImagePart();
                //(FormDb.Db["Form1"] as Form1).PaperFalse();
            }
            catch
            {

            }

        }

        public void Refresh(bool paper = false)
        {
            try
            {
                customBarChartControl1.zCount = ngCount + okCount;
                customBarChartControl1.Data = ngDictionary;
                framesTimeForm.customBarChartControl1.zCount = ngCount + okCount;
                framesTimeForm.customBarChartControl1.Data = ngDictionary;
                if (paper)
                {

                    SetNgDic();
                }
            }
            catch
            {

            }
        }
        public void SetNgDic()
        {
            try
            {
                string ngCountFilePath = Path.Combine("Data", "工程文件", this.projectName, $"{this.name}任务文件", "运行结果", "ng分析.dat");
                HelpJsons.SerializeKeyValuePairs(ngDictionary, ngCountFilePath);
            }
            catch
            {

            }

        }

        public void HSmartWindowControl1_MouseWheel(object sender, MouseEventArgs e)
        {
            try
            {

                hSmartWindowControl1.HSmartWindowControl_MouseWheel(sender, e);
            }
            catch
            {

            }
        }

        /// <summary>
        /// 开始拖拽
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeView1_ItemDrag(object sender, ItemDragEventArgs e)
        {
            //DoDragDrop(e.Item, DragDropEffects.Move);
        }
        /// <summary>
        /// 拖入工作区   
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeView1_DragEnter(object sender, DragEventArgs e)
        {
            try
            {

                e.Effect = DragDropEffects.Move;
            }
            catch
            {

            }
        }
        /// <summary>
        /// 拖放完成时
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeView1_DragDrop(object sender, DragEventArgs e)
        {
            try
            {
                //终点节点坐标
                Point dropPoint = treeView1.PointToClient(new Point(e.X, e.Y));
                //终点节点
                TreeNode targetNode = treeView1.GetNodeAt(dropPoint);

                if (targetNode == null)
                {
                    // 拖拽到TreeView的空白区域，可以根据需要处理  
                    return;
                }
                //当前节点
                TreeNode draggedNode = (TreeNode)e.Data.GetData(typeof(TreeNode));
                //
                if (draggedNode.Parent != null)
                {
                    return;
                }
                // 防止节点移动到其子节点或自己内部  
                if (draggedNode.Parent == targetNode)
                {
                    return;
                }

                //判断头部
                if (targetNode.Index == 0 && targetNode.Parent == null)
                {
                    draggedNode.Remove();
                    treeView1.Nodes.Insert(0, draggedNode);
                    //末尾节点
                }
                else if (targetNode.Index == treeView1.Nodes.Count - 1 && targetNode.Parent == null)
                {
                    draggedNode.Remove();
                    treeView1.Nodes.Add(draggedNode);
                }
                else
                {
                    // 移动节点  
                    if (targetNode.Parent == null && draggedNode.Parent == null)
                    {
                        int index = treeView1.Nodes.IndexOf(targetNode);
                        // 拖拽到根节点  
                        draggedNode.Remove();
                        treeView1.Nodes.Insert(index, draggedNode);
                    }
                    else
                    {
                        //判断是不是子节点,必须要两个节点都没有父节点
                        if (draggedNode.Parent != null && targetNode.Parent != null)
                        {
                            Graphics gh = treeView1.CreateGraphics();
                            Pen pen = new Pen(Color.Red);

                            gh.DrawLine(pen, dropPoint, new Point(200));
                        }
                        return;
                    }
                }
                // 可选：确保拖动的节点是可见的  
                treeView1.SelectedNode = draggedNode;
                if (targetNode != null)
                {
                    DisconnectLink(targetNode);
                }
                if (draggedNode != null)
                {
                    DisconnectLink(draggedNode);
                }
            }
            catch
            {

            }
        }
        /// <summary>
        /// 拖放完成后 断开不正确的连接
        /// </summary>
        private void DisconnectLink(TreeNode node)
        {
            try
            {
                int index = treeView1.Nodes.IndexOf(node);
                TreeNodeCollection childNodes = node.Nodes;
                foreach (TreeNode childNode in childNodes)
                {
                    if (!childNode.Text.Contains("<—")) continue;
                    string[] values = childNode.Text.Split(new char[] { '—', '<', '.' }, StringSplitOptions.RemoveEmptyEntries);
                    bool paper = true;
                    for (int i = 0; i < index; i++)
                    {
                        if (treeView1.Nodes[i].Text == values[1])
                        {
                            paper = false;
                        }
                    }
                    if (paper)
                    {
                        childNode.Text = childNode.Name;
                        childNode.ForeColor = Color.Black;
                    }
                }
            }
            catch
            {

            }
        }
        /// <summary>
        /// 双击打开页面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeView1_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            try
            {

                form1Controller.ShowForm(e.Node.Tag);
            }
            catch
            {

            }
        }

        /// <summary>
        /// 运行(下一张图片)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void toolStripButton1_Click(object sender, EventArgs e)
        {
            try
            {
                Stopwatch runTime = new Stopwatch();
                runTime.Start();
                //是否执行结果分析
                //结果分析工具帮助集合
                Dictionary<List<bool>, string> resultHelper = new Dictionary<List<bool>, string>();
                Stopwatch stopwatch = new Stopwatch();
                string noweDate = DateTime.Now.ToString("MM:dd:HH:mm:ss");
                (FormDb.Db["Form1"] as Form1).textBox1.AppendText("当前工位：" + this.name + " 运行完成 \r\n");
                if (treeView1.Nodes == null || treeView1.Nodes.Count == 0) return;
                //获取相机的图片
                HObject camerImage = null;
                TreeNode camerNode = treeView1.Nodes[0];
                CamerFormController camerObj = camerNode.Tag.GetType().GetField("controller").GetValue(camerNode.Tag) as CamerFormController;
                //更新图像到本句柄中(要本相机类型的)

                //执行模板匹配 获取模板的数据
                double[] HideOutputArrayRows = new double[0];
                double[] HideOutputArrayColumns = new double[0];
                double[] HideOutputArrayPhis = new double[0];
                try
                {
                    stopwatch.Start();
                    camerObj.Run();
                    stopwatch.Stop();
                    camerImage = camerObj.HideOutputImage;
                    this.hImage = camerImage;  //给当前图像,后续进行图像保存
                    HOperatorSet.ClearWindow(hSmartWindowControl1.HalconWindow);
                    HOperatorSet.DispObj(camerImage, hSmartWindowControl1.HalconWindow);
                    //图像居中
                    hSmartWindowControl1.SetFullImagePart();
                    camerNode.ForeColor = Color.Black;

                    (FormDb.Db["Form1"] as Form1).textBox1.AppendText("当前时间：" + noweDate + "     " + treeView1.Nodes[0].Text + "运行成功 ！     执行时间:" + stopwatch.ElapsedMilliseconds.ToString() + "ms\r\n");
                    treeView1.Nodes[0].ForeColor = Color.Black;


                }
                catch (Exception ex)
                {

                    if (ex.InnerException != null)
                    {
                        (FormDb.Db["Form1"] as Form1).textBox1.AppendText(camerNode.Name + ":" + ex.InnerException.Message + "  " + noweDate + "\r\n");
                        camerNode.ForeColor = Color.Red;
                    }
                    else
                    {
                        if (ex.Message.Contains(ex.Message))
                        {
                            (FormDb.Db["Form1"] as Form1).textBox1.AppendText(camerNode.Name + ": 出错\r\n");
                            camerNode.ForeColor = Color.Red;
                        }
                        else
                        {
                            (FormDb.Db["Form1"] as Form1).textBox1.AppendText(camerNode.Name + ":" + ex.Message + "  " + noweDate + "\r\n");
                            camerNode.ForeColor = Color.Red;

                        }

                    }
                }

                TreeNode pmaNode = null;
                try
                {
                    int PmaPaper = -1;
                    //要判断有没有PMA工具
                    for (int i = 0; i < treeView1.Nodes.Count; i++)
                    {
                        if (treeView1.Nodes[i].Text.Contains("多目标"))
                        {
                            PmaPaper = i;
                        }
                    }
                    if (PmaPaper != -1)
                    {
                        pmaNode = treeView1.Nodes[PmaPaper];
                        H_PMA_S_AlignToolForm pma = (pmaNode.Tag as H_PMA_S_AlignToolForm);
                        Shap_S_Matching model = (pmaNode.Tag.GetType().GetField("controller").GetValue(pmaNode.Tag) as Shap_S_Matching);
                        //设置图像
                        model.HideIntputImage = camerImage;
                        stopwatch.Start();
                        model.Run();
                        stopwatch.Stop();
                        ShowOk<double>(noweDate, pmaNode.Name, model.HideOutputArrayScores, stopwatch.ElapsedMilliseconds.ToString());

                        pmaNode.ForeColor = Color.Black;
                        HideOutputArrayRows = model.HideOutputArrayRows;
                        HideOutputArrayColumns = model.HideOutputArrayColumns;
                        HideOutputArrayPhis = model.HideOutputArrayPhis;
                    }
                }
                catch (Exception ex)
                {
                    if (pmaNode != null && ex.InnerException != null)
                    {
                        (FormDb.Db["Form1"] as Form1).textBox1.AppendText(camerNode.Name + ":" + ex.InnerException.Message + "  " + noweDate + "\r\n");
                        pmaNode.ForeColor = Color.Red;
                    }
                    else
                    {
                        if (pmaNode != null)
                        {
                            (FormDb.Db["Form1"] as Form1).textBox1.AppendText(camerNode.Name + ":" + ex.Message + "  " + noweDate + "\r\n");
                            pmaNode.ForeColor = Color.Red;
                        }
                    }

                }

                //获取模板匹配控件的对象以及值
                //不是相机类型
                for (int i = 0; i < treeView1.Nodes.Count; i++)
                {
                    TreeNode item = treeView1.Nodes[i];
                    FieldInfo controller = item.Tag.GetType().GetField("controller");
                    if (controller == null) continue;
                    MethodInfo run = controller.GetValue(item.Tag).GetType().GetMethod("Run");
                    if (run == null) continue;
                    //百分率
                    try
                    {
                        if (item.Text.Contains("找圆") || item.Text.Contains("找线"))
                        {
                            //动作对象
                            object control = item.Tag.GetType().GetField("controller").GetValue(item.Tag);
                            //设置图像
                            control.GetType().GetField("HideIntputImage").SetValue(control, camerImage);
                            //设置行数组
                            control.GetType().GetField("HideIntputArrayRows").SetValue(control, HideOutputArrayRows);
                            //设置列数组
                            control.GetType().GetField("HideIntputArrayColumns").SetValue(control, HideOutputArrayColumns);
                            //设置角度数组
                            control.GetType().GetField("HideIntputArrayPhis").SetValue(control, HideOutputArrayPhis);
                            stopwatch.Start();
                            run.Invoke(controller.GetValue(item.Tag), null);
                            stopwatch.Stop();
                            item.ForeColor = Color.Black;
                            //设置角度数组
                            double[] result = control.GetType().GetField("HideOutputArrayDistances").GetValue(control) as double[];


                            ShowOk<double>(noweDate, item.Name, result, stopwatch.ElapsedMilliseconds.ToString());
                        }
                        else if (item.Text.Contains("测量模块"))
                        {

                            CaliperModuleController modelController = (item.Tag.GetType().GetField("controller").GetValue(item.Tag) as CaliperModuleController);
                            if (HideOutputArrayRows.Length > 0)
                            {
                                modelController.HideIntputImage = camerImage;
                                modelController.HideIntputArrayRows = HideOutputArrayRows;
                                modelController.HideIntputArrayColumns = HideOutputArrayColumns;
                                modelController.HideIntputArrayPhis = HideOutputArrayPhis;
                                stopwatch.Start();
                                modelController.Run();
                                stopwatch.Stop();
                                //获取距离转换工具输出的结果
                                double[] values = (item.Tag as CaliperModuleForm).distanceForm.controller.HideOutputArrayDistances;
                                ShowOk<double>(noweDate, item.Name, values, stopwatch.ElapsedMilliseconds.ToString());

                                //将结果分析工具产生的结果收集
                                if ((item.Tag as CaliperModuleForm).analyseForm.comboBox1.Text == "打开")
                                {
                                    resultHelper.Add((item.Tag as CaliperModuleForm).analyseForm.controller.HideOutputResults, item.Name);
                                }
                                item.ForeColor = Color.Black;
                            }
                            else
                            {
                                throw new Exception("未收到模板数据!\r\n");
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        if (ex.InnerException != null)
                        {
                            (FormDb.Db["Form1"] as Form1).textBox1.AppendText("当前时间：" + noweDate + "     " + item.Name + ":" + ex.InnerException.Message + "\r\n");
                            this.Invoke((MethodInvoker)delegate
                            {
                                NgMessage form = NgMessage.GetSingle(item.Name + "运行错误! 流程中断:  " + ex.InnerException.Message);
                                form.Show();
                            });
                        }
                        else
                        {
                            (FormDb.Db["Form1"] as Form1).textBox1.AppendText("当前时间：" + noweDate + "     " + item.Name + "运行错误！\r\n");
                            this.Invoke((MethodInvoker)delegate
                            {
                                NgMessage form = NgMessage.GetSingle(item.Name + "运行错误! 流程中断:  " + ex.Message);
                                form.Show();
                            });
                        }
                        item.ForeColor = Color.Red;
                        break;
                    }
                    finally
                    {
                        try
                        {
                            //实时监控图像
                            if (framesTimeForm != null)
                            {

                                HOperatorSet.DumpWindowImage(out HObject image, hSmartWindowControl1.HalconWindow);
                                HOperatorSet.DispObj(image, framesTimeForm.Hwindow.HalconWindow);
                                framesTimeForm.Hwindow.SetFullImagePart();
                                //将数据显示到界面上
                                try
                                {
                                    framesTimeForm.sumLabel.Text = (okCount + ngCount).ToString();
                                    framesTimeForm.okLabel.Text = okCount.ToString();
                                    framesTimeForm.ngLabel.Text = ngCount.ToString();
                                    double number = okCount / (okCount + ngCount) * 100;
                                    framesTimeForm.okLabelRate.Text = number + "%";
                                    framesTimeForm.ngLabelRate.Text = 100 - number + "%";
                                }
                                catch { }
                            }

                        }
                        catch
                        {

                        }
                    }

                }

                runTime.Stop();
            }
            catch
            {

            }

        }
        /// <summary>
        /// 结果分析工具
        /// </summary>
        public bool ToolAnalysis(ConcurrentDictionary<bool[], string> resultHelper, HObject camerHObject, HWindowContentManager drawData, Stopwatch runStop,bool draw)
        {
            try
            {
                if (resultHelper == null || resultHelper.Count == 0) return true;

                bool hasNgPaper = false;
                string defectName = string.Empty;

                // 分析结果，找到首个不良项
                foreach (var item in resultHelper)
                {
                    if (item.Key.Any(v => !v)) // 如果有NG的标志
                    {
                        hasNgPaper = true;
                        defectName = item.Value;
                        break; // 发现不良直接退出
                    }
                }
                // 执行相应的处理
                if (hasNgPaper)
                {
                    if (treeView1.Nodes.Count > 0)
                    {
                        // 判断当前工位是否有相机工具
                        camerFormController = (treeView1.Nodes[0].Tag as CamerForm)?.controller;
                    }
                    
                    //运行完成后 将ok，ng 等数据显示至窗体
                    ShowResults_New(new string[] { "运行时间：" + runStop.ElapsedMilliseconds + " ms", "NG" }, drawData, camerHObject);
                    DrawingAllHobject(drawData, camerHObject);
                    if (draw)
                    {
                        
                        HOperatorSet.DumpWindowImage(out  camerHObject, hSmartWindowControl1.HalconWindow);
                    }
                  
                    camerFormController?.LevelReversal(); // 输出电平信号
                    ShowNgForm(camerHObject, this.name);            // 显示不良图像
                    (FormDb.Db["Form1"] as Form1).PaperFalse();//将其余的工位置为false,同步计数器
                    WriteImage(camerHObject, false, defectName); // 保存不良图像
                                                                 // runPaper = false;                    // 设置状态

                    return false;
                }
                else
                {
                    return true;
                }
            }
            catch
            {
                return false;
            }
            finally
            {
                resultHelper.Clear();
                resultHelper = null;
            }
        }
        private long _lastWriteImageTicks = 0; // 使用Ticks记录上次调用时间
        /// <summary>
        /// 将合格和不合格的写入文件
        /// </summary>
        /// <param name="hObject"></param>
        /// <param name="result"></param>
        /// <param name="name"></param>
        public async void WriteImage(HObject hObject, bool result, string name)
        {
            try
            {
                long nowTicks = DateTime.Now.Ticks;

                // ng图片所在的路径
                string ngPath = Path.Combine("Data", "工程文件", this.projectName, $"{this.name}任务文件", "运行结果", "ng图片", DateTime.Now.ToString("yyyy_MM_dd"));

                if (!Directory.Exists(ngPath))
                {
                    Directory.CreateDirectory(ngPath);
                }
                if (result == false)
                {
                    // 检查距离上次调用是否超过1秒
                    if (nowTicks - Interlocked.Read(ref _lastWriteImageTicks) < TimeSpan.TicksPerSecond)
                    {
                        return; // 如果不到1秒，直接返回
                    }
                    // 更新上次调用时间
                    Interlocked.Exchange(ref _lastWriteImageTicks, nowTicks);
                    string time = DateTime.Now.ToString("MM月dd日HH时mm分ss秒fff毫秒");
                    string ng = Path.Combine(ngPath, $"{ngCount}_{time}_{name}.png");
                    HOperatorSet.WriteImage(hObject, "png", 0, ng);
                    //原子级加加 减减
                    Interlocked.Decrement(ref okCount);
                    Interlocked.Increment(ref ngCount);
                    //同步csv文件
                    await csvMainForm.controller.WriteToCsvAsync(okCount + ngCount).ConfigureAwait(false);

                    //一个报错暂停其他工位
                    (FormDb.Db["Form1"] as Form1).AllStopAsync(this.name);

                    //以下是细分ng的百分比
                    if (ngDictionary.ContainsKey(name))
                    {
                        ngDictionary[name] = 1 + ngDictionary[name]; // 如果键存在，增加值
                    }
                    else
                    {
                        ngDictionary.Add(name, 1); // 如果键不存在，添加键并赋值
                    }
                    // 获取 TreeView 中所有根节点的键
                    List<string> treeKeys = new List<string>();
                    foreach (TreeNode node in treeView1.Nodes)
                    {
                        treeKeys.Add(node.Text); // 假设节点的 Text 属性与 ngDictionary 的键对应
                    }
                    // 过滤掉 ngDictionary 中不存在于 treeKeys 的项
                    var keysToRemove = ngDictionary.Keys
                        .Where(key => !treeKeys.Contains(key))
                        .ToList(); // 记录需要删除的键、
                    // 从字典中删除这些键
                    foreach (var key in keysToRemove)
                    {
                        ngDictionary.Remove(key);
                    }

                    this.Refresh();

                    string ngCountFilePath = Path.Combine("Data", "工程文件", this.projectName, $"{this.name}任务文件", "运行结果", "ng分析.dat");
                    HelpJsons.SerializeKeyValuePairs(ngDictionary, ngCountFilePath);

                    this.timer1.Enabled = false;
                    this.timer2.Enabled = false;
                    this.timer3.Enabled = false;
                    this.timer5.Enabled = false;
                    if (this.InvokeRequired)
                    {
                        // 如果当前线程不是 UI 线程，使用 BeginInvoke 转到 UI 线程执行
                        this.BeginInvoke((Action)(() =>
                        {
                            // 启动闪烁
                            framesTimeForm.indicatorLight1.State = IndicatorLight.IndicatorState.RedBlinking; // 切换为红色闪烁   
                        }));
                    }
                    //刷新label 刷新日志
                    LabelMessage();
                    UpdateTextBox();
                }
            }
            catch (Exception ex) { }

        }
        private long _lastNgFormShowTicks = 0; // 使用Ticks记录时间
        /// <summary>
        /// 展示ng图片
        /// </summary>
        /// <param name="image"></param>
        public void ShowNgForm(HObject image,string title)
        {
            try
            {
                long nowTicks = DateTime.Now.Ticks;
                if (nowTicks - Interlocked.Read(ref _lastNgFormShowTicks) < TimeSpan.TicksPerSecond)
                {
                    return; // 如果不到1秒，直接返回
                }
                Interlocked.Exchange(ref _lastNgFormShowTicks, nowTicks);

                this.Invoke((MethodInvoker)delegate
                {
                    ImageNgForm form = ImageNgForm.GetSingle().DispImage(image, title);
                    form.StartPosition = FormStartPosition.CenterParent;
                    form.BringToFront();
                    form.Focus();
                    form.ShowDialog();
                   //form.Show();
                });
            }
            catch
            {

            }
        }
        /// <summary>
        /// 字体大小显示
        /// </summary>
        /// <param name="strs"></param>
        /// <param name="hSmartWindowControls"></param>
        public void ShowResults(string[] strs, HSmartWindowControl hSmartWindowControls, HObject image)
        {
            try
            {
                HOperatorSet.GetImageSize(image, out HTuple width, out HTuple height);
                // 获取图像的宽度和高度
                int imageWidth = int.Parse(width.D.ToString());
                int imageHeight = int.Parse(height.D.ToString());

                int fontSize = 0;
                if (imageWidth == 1440)
                {
                    fontSize = 5;
                }

                // 获取图像的宽度，假设你希望文本占据宽度的 80%
                double availableWidth = imageWidth * 0.95;  // 图像宽度的 80%

                // 计算列坐标的间隔，假设有 4 行文本，列坐标平均分配
                double columnSpacing = availableWidth / strs.Length + 1;  // +1 是为了留出一些间隔

                // 固定的行坐标
                double row = 30;  // 所有行统一为 30

                for (int i = 0; i < strs.Length; i++)
                {
                    // 根据下标动态计算列坐标
                    double column = 40 + (i * columnSpacing);  // 基于可用宽度动态计算列坐标
                    if (i == 0)
                    {
                        column = 10;
                    }
                    if (i == 1)
                    {
                        column = column + availableWidth / 14.4;
                    }
                    if (i == 2)
                    {
                        column = column + availableWidth / 19.2;
                    }
                    if (i == 3)
                    {
                        column = column - availableWidth / 288;
                    }
                    // 根据下标设置颜色（传统的 if-else）
                    string color = "black";  // 默认颜色
                    if (i == 0)
                    {
                        color = "black";
                    }
                    else if (i == 1)
                    {
                        color = "green";
                    }
                    else if (i == 2)
                    {
                        color = "red";
                    }
                    else if (i == 3)
                    {
                        color = "green";
                    }

                    // 设置字体和大小，字体大小动态调整
                    //HOperatorSet.SetFont(hSmartWindowControls.HalconWindow, "宋体" + "-Normal-" + fontSize);  // 根据计算的字体大小设置字体
                    HOperatorSet.SetFont(hSmartWindowControls.HalconWindow, $"宋体-Bold-{fontSize}");
                    // 使用 HOperatorSet.DispText 显示文字
                    HOperatorSet.DispText(
                        hSmartWindowControls.HalconWindow,
                        strs[i],          // 显示的文字内容
                        "image",          // 基于图像坐标
                        row,              // 固定行坐标
                        column,           // 根据计算的列坐标
                        color,            // 文字颜色
                        "box",            // 背景框类型
                        0                 // 背景框透明
                    );
                }
            }
            catch (Exception ex)
            {
                // 异常处理
                Console.WriteLine(ex.Message);
            }
        }
        public void ShowResults_New(string[] strs, HWindowContentManager drawData, HObject image)
        {
            try
            {
                HOperatorSet.GetImageSize(image, out HTuple width, out HTuple height);
                // 获取图像的宽度和高度
                int imageWidth = int.Parse(width.D.ToString());
                int imageHeight = int.Parse(height.D.ToString());

                // 设置字体大小，按图像宽度的 5% 来调整字体大小
                //int fontSize = (int)(imageWidth * 0.04);  // 5% 是一个示例比例，可以根据需要调整

                int fontSize = 25;
                // 获取图像的宽度，假设你希望文本占据宽度的 80%
                double availableWidth = imageWidth * 0.95;  // 图像宽度的 80%

                // 计算列坐标的间隔，假设有 4 行文本，列坐标平均分配
                double columnSpacing = availableWidth / 2;  // +1 是为了留出一些间隔

                // 固定的行坐标
                double row = 30;  // 所有行统一为 30

                for (int i = 0; i < strs.Length; i++)
                {
                    // 根据下标动态计算列坐标
                    double column =  (i * columnSpacing)-100;  // 基于可用宽度动态计算列坐标
                    if (i == 0)
                    {
                        column = 10;
                    }
                    // 根据下标设置颜色（传统的 if-else）
                    string color = "black";  // 默认颜色
                    if (i == 0)
                    {
                        color = "black";
                    }
                    else if (i == 1)
                    {
                        column = column + 750;
                        if (strs[i] == "NG")
                        {
                            color = "red";
                        }else
                        {
                            color = "green";
                        }
                    }
                    drawData.AddText(strs[i], new HTuple(row, column), color, fontSize);
                    width?.Dispose();
                    height?.Dispose();
                }
            }
            catch (Exception ex)
            {
                // 异常处理
                Console.WriteLine(ex.Message);
            }
        }
        /// <summary>
        /// 输出日志
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="time"></param>
        /// <param name="name"></param>
        /// <param name="result"></param>
        /// <param name="allTime"></param>
        public void ShowOk<T>(string time, string name, T[] result, string allTime)
        {
            try
            {
                if (result == null) return;
                string str = null;
                if (result is double[])
                {
                    foreach (var item in (result as double[]))
                    {
                        str += "[" + item.ToString("F3") + "]";
                    }

                }
                else
                {
                    foreach (var item in result)
                    {
                        str += "[" + item.ToString() + "]";
                    }
                }

           (FormDb.Db["Form1"] as Form1).textBox1.AppendText("当前时间：" + time + "     " + name + "运行成功 ！     执行时间:" + allTime + "ms     结果值：" + str + "\r\n");
            }
            catch
            {

            }
        }

        /// 右击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeView1_MouseDown(object sender, MouseEventArgs e)
        {
            try
            {
                if (e.Button == MouseButtons.Right)
                {
                    mouseNode = treeView1.GetNodeAt(e.X, e.Y);
                    if (mouseNode != null && (mouseNode.Name.Contains("Int") || mouseNode.Name.Contains("Out") || mouseNode.Name.Contains("IntOrOut")))
                    {
                        //获取父节点
                        TreeNode fatherNode = mouseNode.Parent;
                        //获取父亲节点在treeview的下标
                        int index = treeView1.Nodes.IndexOf(fatherNode);
                        //获取右击菜单
                        ContextMenuStrip context = mouseNode.ContextMenuStrip;
                        //排除没有右击菜单的节点
                        if (context == null) return;
                        (context.Items[0] as ToolStripMenuItem).DropDownItems.Clear();
                        //排除根节点
                        if (index == 0) return;

                        //遍历此节点父节点上面所有节点 
                        for (int i = 0; i < index; i++)
                        {
                            //查找每个根节点下的所有子节点
                            TreeNodeCollection nodes = treeView1.Nodes[i].Nodes;
                            foreach (TreeNode item in nodes)
                            {
                                if (item.Name.Contains("Out"))
                                {
                                    //通过反射 获取当前遍历的节点（字段）
                                    FieldInfo itemInfo = item.Tag.GetType().GetField(item.Name);
                                    //通过反射 获取鼠标右击得到的节点（字段）
                                    FieldInfo mInFo = mouseNode.Tag.GetType().GetField(mouseNode.Name);
                                    //添加右击菜单  --这里我加了一下条件
                                    if (itemInfo.FieldType.Name == mInFo.FieldType.Name)
                                    {
                                        ToolStripMenuItem menuItem1 = new ToolStripMenuItem(treeView1.Nodes[i].Name + "." + item.Name);
                                        menuItem1.Tag = item.Tag;
                                        menuItem1.Click += MenuItem1_Click;
                                        (context.Items[0] as ToolStripMenuItem).DropDownItems.Add(menuItem1);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch
            {

            }
        }
        /// <summary>
        /// 选择连接的输出节点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MenuItem1_Click(object sender, EventArgs e)
        {
            try
            {
                //之后写 本数据<=外部数据
                if (mouseNode != null && mouseNode.ForeColor != Color.Green)
                {
                    //先记录进来之间的节点名字
                    string text = mouseNode.Text;
                    mouseNode.Text = mouseNode.Text + "<—" + (sender as ToolStripMenuItem).Text;
                    mouseNode.ForeColor = Color.Green;
                    //在这里进行数据迭代 反射设置对应字段值
                    //获取所有字段--输出的
                    FieldInfo[] fieldsOut = (sender as ToolStripMenuItem).Tag.GetType().GetFields();
                    //获取所有字段--输入的
                    FieldInfo[] fieldsIn = mouseNode.Tag.GetType().GetFields();

                    object OutValue = null;
                    foreach (FieldInfo field in fieldsOut)
                    {
                        if (field.Name == (sender as ToolStripMenuItem).Text.Substring((sender as ToolStripMenuItem).Text.IndexOf('.') + 1))
                        {
                            OutValue = field.GetValue((sender as ToolStripMenuItem).Tag);
                            break;
                        }
                    }
                    //如果没有图像层则不让连接成功
                    if (OutValue == null) return;

                    foreach (FieldInfo field in fieldsIn)
                    {
                        if (text == field.Name)
                        {
                            field.SetValue(mouseNode.Tag, OutValue);
                            break;
                        }
                    }
                }
            }
            catch
            {

            }
        }
        /// <summary>
        /// 鼠标出现在子节点上方时
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        /// <summary>
        /// 显示原图
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void 原图ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                foreach (TreeNode node in treeView1.Nodes)
                {
                    if (node.Text.Contains("相机工具"))
                    {
                        CamerForm camer = node.Tag as CamerForm;
                        //显示原图
                        if (camer.controller.HideOutputImage != null)
                        {
                            hSmartWindowControl1.HalconWindow.DispObj(camer.controller.HideOutputImage);
                        }
                    }
                }
            }
            catch
            {

            }
        }
        private void treeView1_MouseMove(object sender, MouseEventArgs e)
        {
            try
            {
                TreeViewHitTestInfo hitTestInfo = treeView1.HitTest(e.Location);
                TreeNode node = hitTestInfo.Node;
                if (node == msMoveNode)
                {
                    return;
                }
                msMoveNode = node;
                if (node != null && (node.Name.Contains("Int") || node.Name.Contains("Out")))
                {
                    string str = "null";
                    //获取节点绑定tag对象
                    object controller = node.Tag;
                    FieldInfo field = node.Tag.GetType().GetField(hitTestInfo.Node.Name);
                    if (field.GetValue(controller) != null)
                    {
                        str = field.GetValue(controller).ToString();
                    }
                    if (str == "null")
                    {
                        str = field.FieldType.Name + "<Nothing>";
                    }
                    toolTip1.SetToolTip(treeView1, str);
                    // 假设你有一个方法来获取节点的额外信息  
                    toolTip1.SetToolTip(treeView1, str);
                }
                else
                {
                    toolTip1.SetToolTip(treeView1, string.Empty);
                }
            }
            catch
            {

            }
        }

        private void HwindowFlowNodeUrseControl_Load(object sender, EventArgs e)
        {
            try
            {
                //写入文件夹
                string ngCountFilePath = Path.Combine("Data", "工程文件", this.projectName, $"{this.name}任务文件", "运行结果", "显示配置.txt");
                if (File.Exists(ngCountFilePath))
                {
                    toolStripComboBox1.Text = File.ReadAllLines(ngCountFilePath)[0];
                }
                else
                {
                    toolStripComboBox1.SelectedIndex = 0;
                }

                // 总路径
                string station = Path.Combine("Data", "工程文件", this.projectName, $"{this.name}任务文件", "运行结果");
                if (!Directory.Exists(station))
                {
                    Directory.CreateDirectory(station);
                }

                string okFilePath = Path.Combine(station, "ok配置.txt");
                string ngFilePath = Path.Combine(station, "ng配置.txt");
                string ngDatFilePath = Path.Combine(station, "ng分析.dat");

                ngDictionary = HelpJsons.DeserializeKeyValuePairs(ngDatFilePath);
                this.Refresh();
                // 读取或创建 OK 文件
                okCount = ReadOrCreateFile(okFilePath);
                //图片检测数同步
                ImageCount = okCount;
                // 读取或创建 NG 文件
                ngCount = ReadOrCreateFile(ngFilePath);

                ContextMenuStrip contex = new ContextMenuStrip();
                //增加一个复制事件
                contex.Items.Add("粘贴节点", Image.FromFile("Data\\Image\\粘贴_paste.png"));
                contex.Items[0].Click += form1Controller.Form1Stickup_Click1;
                contex.Items[0].Tag = treeView1;

                treeView1.ContextMenuStrip = contex;

                csvMainForm = new CsvMainForm(this, $"Data\\工程文件\\{this.projectName}\\{this.name}任务文件", this.name);
                LabelMessage();
                customBarChartControl1.zCount = ngCount + okCount;
                framesTimeForm.customBarChartControl1.zCount = ngCount + okCount;
                customBarChartControl1.Data = ngDictionary;
                framesTimeForm.customBarChartControl1.Data = ngDictionary;
            }
            catch
            {
                //  MessageBox.Show("HwindowFlowNodeUrseControl_Load");
            }
        }
        private int ReadOrCreateFile(string filePath)
        {
            try
            {
                // 如果文件不存在，创建文件并写入默认值 0
                if (!File.Exists(filePath))
                {
                    File.WriteAllText(filePath, "0", Encoding.UTF8);
                    return 0;  // 返回默认值
                }
                // 如果文件存在，读取并返回值
                return int.Parse(File.ReadAllText(filePath, Encoding.UTF8));
            }
            catch
            {
                return 0;
            }
        }

        /// <summary>
        /// 保存图片按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            try
            {
                string path = $"Data\\训练图像\\";
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
                HOperatorSet.DumpWindowImage(out HObject image, this.hSmartWindowControl1.HalconWindow);
                string fileName = path + DateTime.Now.ToString("yyyy年MM月dd日HH时mm分ss秒fff毫秒_即时保存图片");
                HOperatorSet.WriteImage(image, "png", 0, fileName);
                MessageBox.Show("保存成功", "提示");
            }
            catch
            {

            }
        }

        /// <summary>
        /// 重新开始计数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void toolStripButton3_Click(object sender, EventArgs e)
        {
            try
            {
                // 禁用按钮，防止重复点击
                toolStripButton3.Enabled = false;
                try
                {
                    // 显示确认框
                    DialogResult result = MessageBox.Show(
                        "请确保当前软件在非运行状态 您确定要执行此操作吗？",
                        "确认操作",
                        MessageBoxButtons.YesNo,
                        MessageBoxIcon.Question
                    );

                    if (result == DialogResult.Yes)
                    {
                        bool paper = false;
                        if (camerFormController != null)
                        {
                            if (camerFormController.triggerModePaper && camerFormController.triggerSourcePaper && runPaper)
                            {
                                paper = true;
                                MessageBox.Show("软件正在运行状态！ 请点击左侧菜单停止按钮以正确执行该操作", "无法操作", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            }
                        }
                        if (!paper)
                        {


                            ExecuteAction(); // 执行确认操作
                        }
                    }
                }
                finally
                {
                    // 对话框关闭后，重新启用按钮
                    toolStripButton3.Enabled = true;
                }
            }
            catch
            {

            }
        }
        // 示例方法：需要执行的操作
        public void ExecuteAction(int paper = 0)
        {
            try
            {
                // 总路径
                string station = Path.Combine("Data", "工程文件", this.projectName, $"{this.name}任务文件", "运行结果");

                //清理ng计数
                foreach (var key in ngDictionary.Keys.ToList())
                {
                    ngDictionary[key] = 0;
                }
                this.Refresh();

                //这里还要清除饼状图计数NGOK率
                this.ngCount = 0;
                this.okCount = 0;
                this.ImageCount = 0;
                string okFilePath = Path.Combine(station, "ok配置.txt");
                string ngFilePath = Path.Combine(station, "ng配置.txt");
                string ngDatFilePath = Path.Combine(station, "ng分析.dat");
                using (StreamWriter writer = new StreamWriter(okFilePath, append: false))
                {
                    writer.WriteLine("0");
                }
                using (StreamWriter writer = new StreamWriter(ngFilePath, append: false))
                {
                    writer.WriteLine("0");
                }
                HelpJsons.SerializeKeyValuePairs(ngDictionary, ngDatFilePath);
                LabelMessage();

                if (treeView1.Nodes.Count > 0)
                {
                    csvMainForm?.controller?.ClearCsv();
                }
                if (paper == 0)
                {
                    MessageBox.Show("清理操作已执行！", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            catch
            {

            }
        }
        // 使用线程安全的 ConcurrentQueue 替代 List<StringBuilder>
        private ConcurrentQueue<string> msQueue = new ConcurrentQueue<string>();
        //获取线程执行的数据
        public bool runPaper = true;
        /// <summary>
        /// 创建临时窗体的对象池 一般模板匹配的1.2 
        /// </summary>
        private ObjectPool<ConcurrentDictionary<bool[], string>> resultHelperPool = new ObjectPool<ConcurrentDictionary<bool[], string>>(60);
        /// <summary>
        /// 创建多模块数据的对象池 一般模板匹配的1.5
        /// </summary>
        private ObjectPool<ConcurrentDictionary<int, HardRunLineData>> threadDataPool = new ObjectPool<ConcurrentDictionary<int, HardRunLineData>>(100);
        /// <summary>
        /// 计时器对象池1 
        /// </summary>
        private ObjectPool<Stopwatch> runTimePool = new ObjectPool<Stopwatch>(60);
        /// <summary>
        /// 计时器对象池1 
        /// </summary>
        private ObjectPool<Stopwatch> stopwatchPool = new ObjectPool<Stopwatch>(60);

        /// <summary>
        /// 图像硬触发数据集合
        /// </summary>
        public ConcurrentQueue<HObject> imageHardRunData = new ConcurrentQueue<HObject>();

        /// <summary>
        /// 管理所有绘制数据的对象池
        /// </summary>
        private ObjectPool<HWindowContentManager> drawDataPool = new ObjectPool<HWindowContentManager>(60);


        /// <summary>
        /// 当前检测图片的编号
        /// </summary>
        public int ImageCount = 0;
        /// <summary>
        /// 创建多模块数据的对象池 一般模板匹配的1.5
        /// </summary>
        private ObjectPool<ConcurrentDictionary<int, HardRunLineData>> caliperModuleDataPool = new ObjectPool<ConcurrentDictionary<int, HardRunLineData>>(100);

        private  TimeSpan cooldownTime = TimeSpan.FromSeconds(2);  // 冷却时间
        private static DateTime lastTime = DateTime.MinValue;  // 上次垃圾回收时间
        /// <summary>
        /// 每隔 n 秒硬触发一次
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void HardRunTimer_Tick(object sender, EventArgs e)
        {
            try
            {
                //弹出需要检测的图片，无则retrun
                if (!imageHardRunData.TryDequeue(out HObject image) || image == null || !image.IsInitialized()) return;
                //同步没有消耗完的生产者 
                if (!runPaper)
                {
                    await Task.Run(async () =>
                    {
                        await Task.Delay(1000).ConfigureAwait(false);
                        while (imageHardRunData.TryDequeue(out HObject noImage))
                        {
                            noImage.Dispose();
                        }
                    }).ConfigureAwait(false);
                }
                //每隔1200次清理一次
                if ((okCount + ngCount) % 1200 == 0)
                {
                    hSmartWindowControl1.HalconWindow.ClearWindow();
                    framesTimeForm.Hwindow.HalconWindow.ClearWindow();
                }
                if (DateTime.Now - lastTime > cooldownTime)
                {
                    hSmartWindowControl1.SetFullImagePart();
                    framesTimeForm.Hwindow.SetFullImagePart();
                }
                lastTime = DateTime.Now;  // 更新回收时间
                if (treeView1.Nodes.Count < 2)
                {
                    //显示图片至窗体
                    HOperatorSet.DispObj(image, hSmartWindowControl1.HalconWindow);
                    //hSmartWindowControl1.SetFullImagePart();
                    HOperatorSet.DispObj(image, framesTimeForm.Hwindow.HalconWindow);
                    //framesTimeForm.Hwindow.SetFullImagePart();
                    return;
                };

                //模板匹配，开始执行
                await Task.Run(async () =>
                {
                    //当前执行的图片编号
                    ImageCount++; ;
                    //获取当前时间
                    string currentTime = DateTime.Now.ToString("MM月dd日HH时mm分ss秒FFF毫秒");
                    //初始化模板匹配收集的数据
                    double[] HideOutputArrayRows = null;
                    double[] HideOutputArrayColumns = null;
                    double[] HideOutputArrayPhis = null;
                    double[] HideOutputArrayScores = null;

                    ////区域联合对象
                    HWindowContentManager drawData = drawDataPool.Rent();
                    ////计时器工具1 算子工具的计时器
                    Stopwatch toolStop = stopwatchPool.Rent();
                    ////计时器工具2 全局的计时器
                    Stopwatch runStop = stopwatchPool.Rent();
                    ////收集日志信息和textbox信息
                    StringBuilder message = stringBuilderPool.Rent();
                    message?.Append($"当前工位：{this.name} 运行次数：{ngCount + this.ImageCount}  当前时间：{currentTime}\r\n"); //首先记录当前检测的硬触发序号

                    ////计算精准测量模块的个数 并提前初始化好 卡尺的数据一共只有四列 严格初始化好
                    int cailberCount = treeView1.Nodes.Count - 2;
                    List<string> csvResults = Enumerable.Repeat(string.Empty, 2 + 4 * cailberCount).ToList();
                    csvResults[0] = (this.ImageCount + ngCount).ToString();//记录序号 也就是当前检测的图片序号

                    try
                    {
                        try
                        {
                            ////全局计时器 — 开始计时
                            runStop.Start();
                            //开始计时
                            toolStop.Start();
                            //模板匹配
                            Shap_S_Matching.HardRunMatching(image, (H_PMA_S_AlignToolForm)treeView1.Nodes[1].Tag, ref HideOutputArrayRows, ref HideOutputArrayColumns, ref HideOutputArrayPhis, ref HideOutputArrayScores, drawData);
                            //停止并统计计时
                            toolStop.Stop();
                            ////记录模板匹配运行完成的数据
                            message?.Append(ShowMessage(treeView1.Nodes[1].Name, HideOutputArrayScores, toolStop.ElapsedMilliseconds.ToString()));
                            //将模板匹配的数据插入至csv文件
                            csvResults[1] = ConvertArrayToString<double>(HideOutputArrayScores);
                            //同步当前节点的颜色 
                            if ((treeView1.Nodes[1].ForeColor == Color.Red))
                            {
                                treeView1.Nodes[1].ForeColor = Color.Black;
                            }
                        }
                        catch (Exception ex)
                        {
                            if (runPaper && camerFormController.triggerModePaper && camerFormController.triggerSourcePaper)
                            {
                                //将 runPaper = false 置为flase的同时同步运行总数
                                (FormDb.Db["Form1"] as Form1).PaperFalse();
                                //输出电平信号
                                camerFormController?.LevelReversal();
                                //同步一下csv文件
                                for (int i = 1; i < csvResults.Count; i++)
                                {
                                    csvResults[i] = "模板匹配出错";
                                }
                                csvMainForm.controller.AddData(csvResults);

                                //同步一下日志 和 textbox *******
                                message.Append(treeView1.Nodes[1].Name.ToString() + "出错！！！\r\n");
                                msQueue.Enqueue(string.Join(Environment.NewLine, message.ToString()));

                                //手动选择‘处理图’和‘非处理图’********** 最后执行效果好
                                if (toolStripComboBox1.Text == "处理图")
                                {
                                    //停止计时
                                    runStop.Stop();
                                    //运行完成后 将ok，ng 等数据显示至窗体
                                    ShowResults_New(new string[] { "运行时间：" + runStop.ElapsedMilliseconds + " ms", "NG" }, drawData, image);
                                    //展示绘制的画面 异常情况可能不会触发这个方法
                                    drawData.RenderToWindowNg(hSmartWindowControl1, image);
                                    drawData.RenderToWindowNg(framesTimeForm.Hwindow, image);
                                    drawData.ClearDrawQueue();
                                    //展示ng画面
                                    HOperatorSet.DumpWindowImage(out HObject nImage, hSmartWindowControl1.HalconWindow);
                                    WriteImage(nImage, false, treeView1.Nodes[1].Name);
                                    ShowNgForm(nImage, this.name);
                                    nImage.Dispose();
                                }
                                else
                                {
                                    WriteImage(image, false, treeView1.Nodes[1].Name);
                                    ShowNgForm(image, this.name);
                                }
                                treeView1.Nodes[1].ForeColor = Color.Red;

                            }
                        }
                        // //模板匹配出错时无法进入精准测量模块的
                        if (!runPaper) return;
                        // // ******* 以下时精准测量模块的逻辑  ******

                        ConcurrentDictionary<int, HardRunLineData> cailperThreadData = threadDataPool.Rent();
                        //收集结果分析的值
                        ConcurrentDictionary<bool[], string> resultHelper = resultHelperPool.Rent();
                        resultHelper.Clear();
                        //线程对象
                        List<Task> tasks = new List<Task>();// 待释放 ok

                        if (!runPaper) return;

                        //开始执行精准测量模块
                        for (int i = 2; i < treeView1.Nodes.Count; i++)
                        {
                            int k = i - 2;
                            HardRunLineData data = new HardRunLineData();
                            cailperThreadData.TryAdd(k, data);

                            tasks.Add(Task.Run(() =>
                            {
                                int localK = k;
                                if (runPaper)
                                {
                                    CaliperModuleRun(localK, treeView1.Nodes[localK + 2], cailperThreadData, image, drawData, resultHelper, toolStop, message, csvResults, HideOutputArrayRows,
                                HideOutputArrayColumns, HideOutputArrayPhis, HideOutputArrayScores);
                                }

                            }));
                            await Task.Delay(3).ConfigureAwait(false);
                        }
                        await Task.WhenAll(tasks).ConfigureAwait(false);

                        if (!runPaper) return;

                        try
                        {

                            int baseIndex = 2; // 从 2 开始填充
                            for (int i = 0; i < cailperThreadData.Count; i++)
                            {
                                if (cailperThreadData.TryGetValue(i, out HardRunLineData data))
                                {
                                    // 一次性分配结果，避免多次操作
                                    csvResults[baseIndex + i * 4] = data.HideOutputArrayDistancesCailper != null
                                        ? ConvertArrayToString(data.HideOutputArrayDistancesCailper)
                                        : string.Empty;

                                    csvResults[baseIndex + i * 4 + 1] = data.HideOutputArrayDistancesDistance != null
                                        ? ConvertArrayToString(data.HideOutputArrayDistancesDistance)
                                        : string.Empty;

                                    csvResults[baseIndex + i * 4 + 2] = data.HideOutputResultsAna != null && data.HideOutputResultsAna.Length > 0
                                        ? ConvertArrayToString(data.HideOutputResultsAna.ToArray())
                                        : "未启用";

                                    csvResults[baseIndex + i * 4 + 3] = data.HideOutputResults间距 != null && data.HideOutputResults间距.Count > 0
                                        ? ConvertArrayToString(data.HideOutputResults间距.ToArray())
                                        : "未启用";
                                }
                            }

                            //*********** 以下时统计所有数据的逻辑
                            //停止计时
                            runStop.Stop();

                            if (!runPaper) return;

                            bool result = true;
                            //运行完成后 结果分析
                            if (toolStripComboBox1.Text == "处理图")
                            {
                              
                                result= ToolAnalysis(resultHelper, image,drawData,runStop,true);
                            }
                            else
                            {
                                result =ToolAnalysis(resultHelper, image,drawData,runStop,false);
                            }

                          // if (!runPaper) return;
                            if (result)
                            {
                                //运行完成后 将ok，ng 等数据显示至窗体
                                ShowResults_New(new string[] { "运行时间：" + runStop.ElapsedMilliseconds + " ms", "OK"}, drawData, image);
                            }
                            //运行完成后 绘制所有区域
                            if (result) {
                                DrawingAllHobject(drawData, image);
                            }
                            //运行完成后，同步日志
                            msQueue.Enqueue(string.Join(Environment.NewLine, message.ToString()));

                            //运行完成后，将数据插入值csv文件的缓冲区
                            csvMainForm.controller.AddData(csvResults);
                        }
                        catch (Exception ex)
                        {
                            //runPaper = false;
                            // MessageBox.Show("最终结果分析异常");
                        }
                        finally
                        {
                            //释放资源
                            caliperModuleDataPool?.Return(cailperThreadData);
                            tasks?.Clear();
                            tasks = null;
                            resultHelperPool.Return(resultHelper);
                        }
                    }
                    catch (Exception ex)
                    {
                        // runPaper = false;
                        // MessageBox.Show("出现了非模板匹配的报错");
                    }
                    finally
                    {
                        //释放所有绘制的区域和硬触发图片对象
                        drawData?.ClearDrawQueue();
                        drawDataPool?.Return(drawData);
                        image?.Dispose();
                        //释放计时器对象和日志message
                        stopwatchPool?.Return(toolStop);
                        stopwatchPool?.Return(runStop);
                        stringBuilderPool?.Return(message);
                        HideOutputArrayRows = null;
                        HideOutputArrayColumns = null;
                        HideOutputArrayPhis = null;
                        HideOutputArrayScores = null;
                    }

                }).ConfigureAwait(false);
            }
            catch
            {

            }
        }
        bool cailperErro = false;
        /// <summary>
        /// 精准测量模块运行的逻辑 使用线程执行，得加倍小心
        /// </summary>
        /// <param name="cailperNode"></param>
        /// <param name="task"></param>
        /// <param name="currentValue"></param>
        public async void CaliperModuleRun(int i, TreeNode cailperNode, ConcurrentDictionary<int, HardRunLineData> cailperThreadData, HObject image, HWindowContentManager drawData, ConcurrentDictionary<bool[], string> resultHelper, Stopwatch toolStop, StringBuilder message, List<string> csvResults, double[] HideOutputArrayRows, double[] HideOutputArrayColumns, double[] HideOutputArrayPhis, double[] HideOutputArrayScores)
        {

            try
            {
                if (!runPaper) return;

                cailperThreadData.TryGetValue(i, out HardRunLineData data);
                //获取精准测量模块窗体数据
                CaliperModuleForm cmoduleForm = (cailperNode.Tag as CaliperModuleForm);
                //获取算子对象
                CaliperModuleController modelController = cmoduleForm.controller;
                //获取卡尺窗体
                PreciseCaliper preciseCaliper = cmoduleForm.caliperForm;
                // 开始计时
                toolStop?.Start();

                if (runPaper)
                {
                    //卡尺工具硬触发MessageBox
                    CaliperModuleController.HardRunCailper(image, preciseCaliper, drawData, HideOutputArrayRows, HideOutputArrayColumns, HideOutputArrayPhis, preciseCaliper.controller.line1counterFrist, preciseCaliper.controller.line2counterFrist, preciseCaliper.controller.pmaListDouble, ref data.HideOutputArrayDistancesCailper, ref data.linesList, ref data.HideOutputArrayRowsCailper, ref data.HideOutputArrayColumnsCailper, preciseCaliper.controller.rectangle1, preciseCaliper.controller.rectangle2);
                }
                else return;

                if (runPaper)
                {
                    //距离转换运行
                    CaliperModuleController.HardRunDistance(cmoduleForm.distanceForm, data.HideOutputArrayDistancesCailper, ref data.HideOutputArrayDistancesDistance);
                }
                else return;

                if (runPaper)
                {
                    //结果分析运行
                    if (cmoduleForm.analyseForm.comboBox1.Text == "打开")
                    {
                        CaliperModuleController.HardRunAnalyse(cmoduleForm.analyseForm, data.HideOutputArrayDistancesDistance, ref data.HideOutputResultsAna);
                        try
                        {
                            resultHelper.TryAdd(data?.HideOutputResultsAna, cailperNode.Name);

                            //resultHelper?.Add(currentValue?.HideOutputResultsAna, cailperNode.Name);
                        }
                        catch (Exception ex)
                        {
                            //MessageBox.Show("值有问题");
                        }

                    }
                }
                else return;

                if (runPaper)
                {
                    //文本显示运行5
                    if (cmoduleForm.messageForm.comboBox4.Text == "打开")
                    {
                        CaliperModuleController.HardRunMessage(cmoduleForm.messageForm, data.HideOutputArrayRowsCailper, data.HideOutputArrayColumnsCailper, drawData, data.HideOutputArrayDistancesDistance, data.HideOutputResultsAna);

                    }
                }
                else return;
                if (runPaper)
                {
                    //间距测量分析 暂时注释
                    if (cmoduleForm.distansceForm.comboBox1.Text == "打开")
                    {
                        //DistanceForm distansceForm = cmoduleForm.distansceForm;
                        //CaliperModuleController.HardRunDistanceS(hSmartWindowControl, distansceForm, currentValue.linesList, ref currentValue.HideOutputResults间距);
                    }

                }
                if (runPaper)
                {
                    toolStop?.Stop();
                    message?.Append(ShowMessage(cailperNode.Name, data.HideOutputArrayDistancesDistance, toolStop?.ElapsedMilliseconds.ToString()));
                    if (cailperNode.ForeColor == Color.Red)
                    {
                        cailperNode.ForeColor = Color.Black;
                    }
                }
                else return;

            }
            catch (Exception ex)
            {
                if (runPaper && camerFormController.triggerModePaper && camerFormController.triggerSourcePaper)
                {
                    if (cailperErro == true) return;
                    cailperErro = true;

                    // runPaper = false; 将所有工位暂停
                    (FormDb.Db["Form1"] as Form1).PaperFalse();
                    //暂时开启
                    //await Task.Run(() =>
                    //{
                    //    MessageBox.Show("" + ex.Message);
                    //    MessageBox.Show("" + ex.StackTrace + $"触发方法: {ex.TargetSite}\n");

                    //    // 提取堆栈信息中的行号
                    //    var stackTrace = new System.Diagnostics.StackTrace(ex, true); // 传递 true 参数，获取源代码行号
                    //    var frame = stackTrace.GetFrame(0); // 获取异常发生时的堆栈帧
                    //    if (frame != null)
                    //    {
                    //        // 获取异常发生的文件名和行号
                    //        string fileName = frame.GetFileName();
                    //        int lineNumber = frame.GetFileLineNumber();

                    //        MessageBox.Show("行数：" + lineNumber);
                    //    }
                    //});
                    camerFormController?.LevelReversal();//输出电平信号
                                                         //收集卡尺插入csv文件的数据  全部打上错误标识 并同步csv文件
                    const string errorMessage = "精准测量模块出错";

                    csvResults[2 + i * 4] = errorMessage;
                    csvResults[3 + i * 4] = errorMessage;
                    csvResults[4 + i * 4] = errorMessage;
                    csvResults[5 + i * 4] = errorMessage;
                    csvMainForm.controller.AddData(csvResults);

                    //同步一下日志
                    message.Append(cailperNode.Name.ToString() + "出错！！！\r\n");
                    string newText = string.Join(Environment.NewLine, message.ToString());
                    msQueue.Enqueue(newText);

                    //ng之后的逻辑
                    if (toolStripComboBox1.Text == "处理图")
                    {
                        toolStop?.Stop();
                        //运行完成后 将ok，ng 等数据显示至窗体
                        ShowResults_New(new string[] { "运行时间：" + toolStop.ElapsedMilliseconds + " ms", "NG" }, drawData, image);

                        //展示绘制的画面 异常情况可能不会触发这个方法
                        drawData.RenderToWindowNg(hSmartWindowControl1, image);
                        drawData.RenderToWindowNg(framesTimeForm.Hwindow, image);
                        drawData.ClearDrawQueue();
                        //展示ng画面
                        HOperatorSet.DumpWindowImage(out HObject nImage, hSmartWindowControl1.HalconWindow);
                        WriteImage(nImage, false, cailperNode.Name);
                        ShowNgForm(nImage, this.name);
                    }
                    else
                    {
                        WriteImage(image, false, cailperNode.Name);
                        ShowNgForm(image, this.name);
                    }

                    cailperNode.ForeColor = Color.Red;

                    //!重点   出现异常可以在此收集

                    await Task.Delay(2000);
                    cailperErro = false;
                }
                return;
            }

        }
        // 用于标识是否有线程正在渲染图像
        private int _isDrawing = 0;
        /// <summary>
        /// 绘制所有区域的方法
        /// </summary>
        public void DrawingAllHobject(HWindowContentManager drawData, HObject image)
        {
            if (Interlocked.Exchange(ref _isDrawing, 1) == 0)
            {
                try
                {
                    //展示绘制的画面 异常情况可能不会触发这个方法
                    drawData.RenderToWindow(hSmartWindowControl1, image);
                    drawData.RenderToWindow(framesTimeForm.Hwindow, image);
                }
                finally
                {
                    // 渲染完成后释放锁
                    Interlocked.Exchange(ref _isDrawing, 0);
                }
            }
        }


        /// <summary>
        /// 异步版本
        /// </summary>
        /// <param name="image"></param>
        public async void HardTriggerRun(HObject image, int okNum)
        {
            try
            {

                if (treeView1.Nodes.Count < 2 || image == null)
                {
                    if (image != null)
                    {
                        HOperatorSet.DispObj(image, hSmartWindowControl1.HalconWindow);
                        hSmartWindowControl1.SetFullImagePart();
                    }
                    return;
                }
                //获取图片宽高
                HOperatorSet.GetImageSize(image, out HTuple width, out HTuple height);
                //全局计时
                Stopwatch runTime = runTimePool.Rent();
                runTime?.Start();
                //收集日志信息
                StringBuilder message = stringBuilderPool.Rent();
                //局部计时
                Stopwatch stopwatch = stopwatchPool.Rent();

                HSmartWindowControl hSmartWindowControl = null;

                // 在主线程中创建 hSmartWindowControl
                // hSmartWindowControl = (HSmartWindowControl)Invoke(new Func<HSmartWindowControl>(() =>
                //{
                //    //return hSmartWindowControlPool.Rent();
                //}));
                try
                {
                    hSmartWindowControl.Size = new Size(width, height);
                    hSmartWindowControl.HalconWindow.ClearWindow();
                    hSmartWindowControl1.HalconWindow.SetWindowParam("graphics_stack_max_element_num", 1000);
                    HOperatorSet.SetDraw(hSmartWindowControl.HalconWindow, "margin");
                    HOperatorSet.DispObj(image, hSmartWindowControl.HalconWindow);
                    hSmartWindowControl.SetFullImagePart();
                }
                catch (HalconDotNet.HOperatorException ex)
                {
                    hSmartWindowControl.Dispose();
                    // 在主线程中创建 hSmartWindowControl
                    hSmartWindowControl = (HSmartWindowControl)Invoke(new Func<HSmartWindowControl>(() =>
                   {
                       return new HSmartWindowControl();
                   }));
                    hSmartWindowControl.Size = new Size(width, height);
                    hSmartWindowControl1.HalconWindow.SetWindowParam("graphics_stack_max_element_num", 1000);
                    HOperatorSet.SetDraw(hSmartWindowControl.HalconWindow, "margin");
                    HOperatorSet.DispObj(image, hSmartWindowControl.HalconWindow);
                    hSmartWindowControl.SetFullImagePart();
                }
                catch (Exception ex)
                {

                }
                //多目标模板匹配窗体
                H_PMA_S_AlignToolForm pmaForm = (treeView1.Nodes[1].Tag as H_PMA_S_AlignToolForm);
                Shap_S_Matching pmaController = pmaForm.controller;

                //计算精准测量模块的个数
                int x = treeView1.Nodes.Count - 2;
                List<string> visionResults;
                if (x > 0)
                {
                    //收集所有算子的结果，输出至外部csv文件
                    visionResults = Enumerable.Repeat(string.Empty, 2 + 5 * x).ToList();
                }
                else
                {
                    //收集所有算子的结果，输出至外部csv文件
                    visionResults = Enumerable.Repeat(string.Empty, 2).ToList();
                }

                //执行模板匹配 获取模板的数据
                double[] HideOutputArrayRows = new double[0];
                double[] HideOutputArrayColumns = new double[0];
                double[] HideOutputArrayPhis = new double[0];
                double[] HideOutputArrayScores = new double[0];
                try
                {
                    if (runPaper && camerFormController.triggerModePaper && camerFormController.triggerSourcePaper)
                    {
                        message?.Append($"当前工位：{this.name} 运行次数：{ngCount + okNum} \r\n");
                        stopwatch.Start();
                        visionResults[0] = (okNum + ngCount).ToString();
                        Shap_S_Matching.HardRun(image, pmaForm.filePath, pmaForm, pmaController.searchArea, hSmartWindowControl, ref HideOutputArrayRows, ref HideOutputArrayColumns, ref HideOutputArrayPhis, ref HideOutputArrayScores);
                        // 直接等待 task 完成
                        stopwatch.Stop();
                        message?.Append(ShowMessage(treeView1.Nodes[1].Name, HideOutputArrayScores, stopwatch.ElapsedMilliseconds.ToString()));
                        Interlocked.Exchange(ref pmaController.HideIntputImage, image);
                        Interlocked.Exchange(ref pmaController.HideOutputArrayRows, HideOutputArrayRows);
                        Interlocked.Exchange(ref pmaController.HideOutputArrayColumns, HideOutputArrayColumns);
                        Interlocked.Exchange(ref pmaController.HideOutputArrayPhis, HideOutputArrayPhis);
                        if (treeView1.Nodes[1].ForeColor == Color.Red)
                        {
                            treeView1.Nodes[1].ForeColor = Color.Black;
                        }
                        visionResults[1] = ConvertArrayToString<double>(HideOutputArrayScores);
                    }
                    else
                    {
                        //hSmartWindowControlPool.Return(hSmartWindowControl);
                        stringBuilderPool.Return(message);
                        runTimePool.Return(runTime);
                        stopwatchPool.Return(stopwatch);
                    }
                }
                catch (Exception ex)
                {

                    if (runPaper && camerFormController.triggerModePaper && camerFormController.triggerSourcePaper)
                    {
                        //runPaper = false;
                        (FormDb.Db["Form1"] as Form1).PaperFalse();
                        //展示ng画面
                        HOperatorSet.DumpWindowImage(out HObject nImage, hSmartWindowControl.HalconWindow);
                        HOperatorSet.DispObj(nImage, hSmartWindowControl1.HalconWindow);
                        HOperatorSet.DispObj(nImage, framesTimeForm.Hwindow.HalconWindow);
                        framesTimeForm.Hwindow.SetFullImagePart();
                        hSmartWindowControl1.SetFullImagePart();

                        //同步一下csv文件
                        visionResults[1] = "模板匹配出错";
                        for (int i = 1; i < visionResults.Count; i++)
                        {
                            visionResults[i] = "模板匹配出错";
                        }
                        csvMainForm.controller.AddData(visionResults);
                        //同步一下日志
                        message.Append(pmaForm.Name.ToString() + "出错！！！\r\n");

                        HObject ts = image.Clone();
                        if (toolStripComboBox1.Text == "处理图")
                        {
                            //ShowNgForm(nImage, treeView1.Nodes[1].Name);
                            WriteImage(nImage, false, treeView1.Nodes[1].Name);
                        }
                        else
                        {
                           // ShowNgForm(ts, treeView1.Nodes[1].Name);
                            WriteImage(ts, false, treeView1.Nodes[1].Name);
                        }

                        string newText = string.Join(Environment.NewLine, message.ToString());

                        msQueue.Enqueue(newText);

                        if (treeView1.Nodes.Count > 0)//判断当前工位有没有相机工具
                        {
                            camerFormController = (treeView1.Nodes[0].Tag as CamerForm).controller;
                        }
                        if (camerFormController != null)
                        {
                            camerFormController.LevelReversal();//输出电平信号
                        }
                    }
                    stringBuilderPool.Return(message);
                    runTimePool.Return(runTime);
                }
                // 以上是模板匹配 以下是模块测量*************************************

                //结果分析工具帮助集合 获取对象池对象
                //拿出来的时候洗一遍
                //Dictionary<List<bool>, string> resultHelper = resultHelperPool.Rent();
                //resultHelper.Clear();

                ConcurrentDictionary<int, HardRunLineData> threadData = threadDataPool.Rent();
                threadData.Clear();
                for (int i = 0; i < x; i++)
                {
                    threadData.TryAdd(i + 2, new HardRunLineData());
                }
                //线程集合
                // List<Task> tasks = new List<Task>();

                //执行其他节点
                for (int j = 2; j < treeView1.Nodes.Count; j++)
                {
                    int i = j;
                    TreeNode item = treeView1.Nodes[i];
                    if (item.Text.Contains("测量模块") && runPaper && camerFormController.triggerModePaper && camerFormController.triggerSourcePaper)
                    {
                        if (runPaper == false) break;
                        await Task.Run(async () =>
                     {
                         await Task.Delay(1).ConfigureAwait(false);
                         try
                         {
                             if (threadData.TryGetValue(i, out var data))
                             {
                                 //获取精准测量模块窗体数据
                                 CaliperModuleForm cmoduleForm = (item.Tag as CaliperModuleForm);
                                 //获取算子对象
                                 CaliperModuleController modelController = cmoduleForm.controller;
                                 //获取卡尺窗体
                                 PreciseCaliper preciseCaliper = cmoduleForm.caliperForm;
                                 stopwatch?.Start();
                                 //卡尺工具硬触发MessageBox
                                 // CaliperModuleController.HardRunCailper(image, preciseCaliper, hSmartWindowControl, HideOutputArrayRows, HideOutputArrayColumns, HideOutputArrayPhis, preciseCaliper.controller.line1counterFrist, preciseCaliper.controller.line2counterFrist, preciseCaliper.controller.pmaListDouble, ref data.HideOutputArrayDistancesCailper, ref data.linesList, ref data.HideOutputArrayRowsCailper, ref data.HideOutputArrayColumnsCailper, width, height, preciseCaliper.controller.rectangle1, preciseCaliper.controller.rectangle2);

                                 //距离转换运行
                                 CaliperModuleController.HardRunDistance(cmoduleForm.distanceForm, data.HideOutputArrayDistancesCailper, ref data.HideOutputArrayDistancesDistance);
                                 //结果分析运行
                                 if (cmoduleForm.analyseForm.comboBox1.Text == "打开")
                                 {
                                     //CaliperModuleController.HardRunAnalyse(cmoduleForm.analyseForm, data.HideOutputArrayDistancesDistance, ref data.HideOutputResultsAna);
                                     //resultHelper?.Add(data?.HideOutputResultsAna, item.Name);
                                     //try
                                     //{
                                     //    resultHelper?.Add(data?.HideOutputResultsAna, item.Name);
                                     //}
                                     //catch
                                     //{
                                     //   // MessageBox.Show(i + "  重复了");
                                     //}
                                 }
                                 //文本显示运行5
                                 if (cmoduleForm.messageForm.comboBox4.Text == "打开")
                                 {
                                     // CaliperModuleController.HardRunMessage(cmoduleForm.messageForm, data.HideOutputArrayRowsCailper, data.HideOutputArrayColumnsCailper, hSmartWindowControl, data.HideOutputArrayDistancesDistance, data.HideOutputResultsAna);

                                 }
                                 //间距测量分析
                                 if (cmoduleForm.distansceForm.comboBox1.Text == "打开")
                                 {
                                     DistanceForm distansceForm = cmoduleForm.distansceForm;
                                     CaliperModuleController.HardRunDistanceS(hSmartWindowControl, distansceForm, data.linesList, ref data.HideOutputResults间距);
                                 }
                                 stopwatch?.Stop();
                                 message?.Append(ShowMessage(item.Name, data.HideOutputArrayDistancesDistance, stopwatch?.ElapsedMilliseconds.ToString()));
                                 if (item.ForeColor == Color.Red)
                                 {
                                     item.ForeColor = Color.Black;
                                 }
                                 //给卡尺窗体赋值
                                 Interlocked.Exchange(ref cmoduleForm.caliperForm.controller.HideIntputImage, image);
                                 Interlocked.Exchange(ref cmoduleForm.caliperForm.controller.HideIntputArrayRows, HideOutputArrayRows);
                                 Interlocked.Exchange(ref cmoduleForm.caliperForm.controller.HideIntputArrayPhis, HideOutputArrayPhis);
                                 Interlocked.Exchange(ref cmoduleForm.caliperForm.controller.HideIntputArrayColumns, HideOutputArrayColumns);
                                 Interlocked.Exchange(ref cmoduleForm.caliperForm.controller.HideOutputArrayDistances, data.HideOutputArrayDistancesDistance);
                                 //给距离转换窗体赋值
                                 Interlocked.Exchange(ref cmoduleForm.distanceForm.controller.HideIntputArrayDistances, data.HideOutputArrayDistancesCailper);
                                 Interlocked.Exchange(ref cmoduleForm.distanceForm.controller.HideOutputArrayDistances, data.HideOutputArrayDistancesDistance);
                             }

                         }
                         catch (Exception ex)
                         {
                             if (runPaper && camerFormController.triggerModePaper && camerFormController.triggerSourcePaper)
                             {
                                 // runPaper = false;
                                 (FormDb.Db["Form1"] as Form1).PaperFalse();
                                 if (treeView1.Nodes.Count > 0)//判断当前工位有没有相机工具
                                 {
                                     camerFormController = (treeView1.Nodes[0].Tag as CamerForm).controller;
                                 }
                                 if (camerFormController != null)
                                 {
                                     camerFormController.LevelReversal();//输出电平信号
                                 }
                                 //收集卡尺插入csv文件的数据
                                 const string errorMessage = "精准测量模块出错";

                                 for (int k = 0; k < threadData.Count; k++)
                                 {
                                     if (threadData.TryGetValue(k + 2, out var data)) // 使用 TryGetValue 替代 ContainsKey
                                     {
                                         // 默认错误信息
                                         visionResults[2 + k * 4] = errorMessage;
                                         visionResults[3 + k * 4] = errorMessage;

                                         // 处理 HideOutputResultsAna 是否为空
                                         //  visionResults[4 + k * 4] = (data.HideOutputResultsAna != null && data.HideOutputResultsAna.Length > 0)
                                         //? ConvertArrayToString<bool>(data.HideOutputResultsAna.ToArray())
                                         //: errorMessage;

                                         // 处理 HideOutputResults间距 是否为空
                                         visionResults[5 + k * 4] = (data.HideOutputResults间距 != null && data.HideOutputResults间距.Count > 0)
                                             ? ConvertArrayToString<bool>(data.HideOutputResults间距.ToArray())
                                             : errorMessage;
                                     }
                                     else
                                     {
                                         // 如果数据不存在，直接设置错误信息
                                         visionResults[2 + k * 4] = errorMessage;
                                         visionResults[3 + k * 4] = errorMessage;
                                         visionResults[4 + k * 4] = errorMessage;
                                         visionResults[5 + k * 4] = errorMessage;
                                     }
                                 }

                                 //同步一下csv文件
                                 csvMainForm.controller.AddData(visionResults);

                                 item.ForeColor = Color.Red;
                                 //展示ng画面
                                 HOperatorSet.DumpWindowImage(out HObject nImage, hSmartWindowControl.HalconWindow);
                                 HOperatorSet.DispObj(nImage, hSmartWindowControl1.HalconWindow);   
                                 HOperatorSet.DispObj(nImage, framesTimeForm.Hwindow.HalconWindow);
                                 framesTimeForm.Hwindow.SetFullImagePart();
                                 hSmartWindowControl1.SetFullImagePart();

                                 if (toolStripComboBox1.Text == "处理图")
                                 {
                                     //ShowNgForm(nImage, treeView1.Nodes[j].Name);
                                     WriteImage(nImage, false, item.Name);
                                 }
                                 else
                                 {
                                     HObject ts = image.Clone();
                                    // ShowNgForm(ts, treeView1.Nodes[i].Name);
                                     WriteImage(ts, false, item.Name);
                                 }
                                 //同步一下日志
                                 message.Append(item.Name.ToString() + "出错！！！\r\n");
                                 string newText = string.Join(Environment.NewLine, message.ToString());
                                 msQueue.Enqueue(newText);

                                 //!重点   出现异常可以在此收集

                             }
                             //hSmartWindowControlPool.Return(hSmartWindowControl);
                             stringBuilderPool.Return(message);
                             //  resultHelperPool.Return(resultHelper);
                             runTimePool.Return(runTime);
                             stopwatchPool.Return(stopwatch);
                         }
                         finally
                         {
                             //semaphoreCailper.Release();
                         }
                     }).ConfigureAwait(false);
                    }
                }
                try
                {
                    // await Task.WhenAll(tasks).ConfigureAwait(false);

                    int baseIndex = 2; // 从 2 开始填充
                    foreach (var kvp in threadData)
                    {
                        int index = kvp.Key; // Key 本身就是字典索引
                        if (index < 2) continue; // 忽略无效 Key

                        var data = kvp.Value;

                        // 一次性分配结果，避免多次操作
                        visionResults[baseIndex + (index - 2) * 4] = data.HideOutputArrayDistancesCailper != null
                            ? ConvertArrayToString(data.HideOutputArrayDistancesCailper)
                            : string.Empty;

                        visionResults[baseIndex + (index - 2) * 4 + 1] = data.HideOutputArrayDistancesDistance != null
                            ? ConvertArrayToString(data.HideOutputArrayDistancesDistance)
                            : string.Empty;

                        //visionResults[baseIndex + (index - 2) * 4 + 2] = data.HideOutputResultsAna != null && data.HideOutputResultsAna.Count > 0
                        //? ConvertArrayToString(data.HideOutputResultsAna.ToArray())
                        //: "未启用";

                        visionResults[baseIndex + (index - 2) * 4 + 3] = data.HideOutputResults间距 != null && data.HideOutputResults间距.Count > 0
                            ? ConvertArrayToString(data.HideOutputResults间距.ToArray())
                            : "未启用";
                    }
                }
                catch
                {

                }
                runTime?.Stop();
                if (runPaper && camerFormController.triggerModePaper && camerFormController.triggerSourcePaper)
                {
                    try
                    {
                        Interlocked.Exchange(ref (treeView1.Nodes[0].Tag as CamerForm).controller.HideOutputImage, image);
                        //同步一下csv文件
                        csvMainForm.controller.AddData(visionResults);

                        //同步一下日志
                        string newText = string.Join(Environment.NewLine, message.ToString());
                        msQueue.Enqueue(newText);

                        HObject ts = image.Clone();
                        HOperatorSet.DumpWindowImage(out HObject nImage, hSmartWindowControl.HalconWindow);
                        if (toolStripComboBox1.Text == "处理图")
                        {
                            //分析工具
                            //  ToolAnalysis(resultHelper, nImage);
                        }
                        else
                        {
                            //分析工具
                            // ToolAnalysis(resultHelper, ts);
                        }
                        long time = runTime.ElapsedMilliseconds;
                        if (runTime.ElapsedMilliseconds > 50)
                        {
                            time = time - 10;

                        }
                        double z = double.Parse((okCount * 100).ToString()) / double.Parse((okCount + ngCount).ToString());
                        ShowResults(new string[] { "运行时间：" + time + " ms", "ok数：" + okCount, "ng数：" + ngCount, "良率：" + Math.Round(z, 3, MidpointRounding.AwayFromZero) + "%" }, hSmartWindowControl, image);
                    }
                    catch (Exception ex)
                    {

                    }
                    finally
                    {

                        if (hSmartWindowControl.HalconWindow != null || hSmartWindowControl1.HalconWindow != null)
                        {
                            if (Interlocked.Exchange(ref _isRendering, 1) == 0)
                            {

                                HOperatorSet.DumpWindowImage(out HObject nImage, hSmartWindowControl.HalconWindow);
                                try
                                {
                                    HOperatorSet.DispObj(nImage, hSmartWindowControl1.HalconWindow);
                                    hSmartWindowControl1.SetFullImagePart();
                                    //实时监控图像
                                    if (framesTimeForm != null)
                                    {
                                        HOperatorSet.DispObj(nImage, framesTimeForm.Hwindow.HalconWindow);
                                        framesTimeForm.Hwindow.SetFullImagePart();
                                    }
                                }
                                finally
                                {
                                    // 渲染完成后释放锁
                                    Interlocked.Exchange(ref _isRendering, 0);
                                    nImage?.Dispose();
                                }
                            }
                        }
                        //  hSmartWindowControlPool.Return(hSmartWindowControl);
                        stringBuilderPool.Return(message);
                        //  resultHelperPool.Return(resultHelper);
                        threadDataPool.Return(threadData);
                        runTimePool.Return(runTime);
                        stopwatchPool.Return(stopwatch);
                        //tasks.Clear();
                    }
                }
                else
                {
                    //hSmartWindowControlPool.Return(hSmartWindowControl);
                    stringBuilderPool.Return(message);
                    // resultHelperPool.Return(resultHelper);
                    threadDataPool.Return(threadData);
                    runTimePool.Return(runTime);
                    stopwatchPool.Return(stopwatch);
                    //  tasks.Clear();
                }
            }
            catch (Exception ex)
            {

            }
        }
        // 用于标识是否有线程正在渲染图像
        private int _isRendering = 0;
        private ObjectPool<StringBuilder> stringBuilderPool2 = new ObjectPool<StringBuilder>(100);
        private static readonly string LogTemplate = "{0}运行成功！     执行时间：{1}ms     结果值：{2}\r\n";

        public string ShowMessage(string name, double[] result, string allTime)
        {
            if (result == null || result.Length == 0) return null;

            // 从对象池获取 StringBuilder 实例
            StringBuilder strBuilder = stringBuilderPool2.Rent();

            try
            {
                strBuilder.EnsureCapacity(result.Length);

                // 使用 StringBuilder 来构建结果字符串，减少内存分配
                // 遍历结果数组，构建字符串
                foreach (var item in result)
                {
                    strBuilder.AppendFormat("[{0:F3}]", item);

                }

                // 使用 StringBuilder 构建最终的日志字符串
                return $"{string.Format(LogTemplate, name, allTime, strBuilder)}";
            }
            catch
            {
                return null;
            }
            finally
            {
                // 使用完后将 StringBuilder 归还给对象池
                stringBuilderPool2.Return(strBuilder);
            }
        }

        /// <summary>
        /// 置为按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void toolStripButton4_Click(object sender, EventArgs e)
        {
            try
            {
                FuWei(1);
                MessageBox.Show("复位成功!", "消息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            catch
            {

            }

        }
        public void FuWei(int i = 0)
        {
            try
            {
                this.BeginInvoke(new Action(() =>
                {
                    if (i == 1)
                    {
                        runPaper = true;
                    }
                    timer2.Enabled = true;
                    timer3.Enabled = true;
                    timer4.Enabled = true;
                    timer5.Enabled = true;
                    timer1.Enabled = true;
                    this.treeView1.Enabled = false;
                    
                    if (camerFormController != null)
                    {
                        if (camerFormController.triggerSourcePaper && camerFormController.triggerModePaper && camerFormController?.device != null)
                        {
                            framesTimeForm.indicatorLight1.State = IndicatorLight.IndicatorState.GreenStable; // 切换为绿色稳定
                            if (i == 0)
                            {
                                try
                                {

                                    MonitoringForm.GetMonitoringForm().参数设置窗口ToolStripMenuItem.Enabled = false;
                                }
                                catch
                                {

                                }
                            }
                        }
                    }
                    
                    //HOperatorSet.SetDraw(framesTimeForm.Hwindow.HalconWindow, "margin");
                    
                }));
            }
            catch
            {
                // MessageBox.Show("toolStripButton4_Click");
            }
        }
        #region 更新label数据
        // 是否正在进行更新
        private bool isUpdating = false;
        /// <summary>
        /// 更新结果分析
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void timer2_Tick(object sender, EventArgs e)
        {
            try
            {
                if (!runPaper)
                {
                    (sender as System.Windows.Forms.Timer).Enabled = false;
                    return;
                }
                else
                {
                    LabelMessage();
                }
            }
            catch
            {
                //MessageBox.Show("timer2_Tick");
            }
        }
        public double antherCount;
        /// <summary>
        /// 更新ng，ok个数以及百分比
        /// </summary>
        public void LabelMessage()
        {
            if (isUpdating) return;
            try
            {

                // 异步执行UI更新，避免阻塞UI线程
                //await Task.Run(async () =>
                //{
                //    await Task.Delay(1);
                //    // 确保UI更新发生在主线程
                //    Invoke(new Action(() =>
                //     {
                //         // 更新所有标签
                //         UpdateLabelTextIfChanged(framesTimeForm.sumLabel, totalCount.ToString());
                //         UpdateLabelTextIfChanged(framesTimeForm.okLabel, localOkCount.ToString());
                //         UpdateLabelTextIfChanged(framesTimeForm.ngLabel, localNgCount.ToString());
                //         UpdateLabelTextIfChanged(framesTimeForm.okLabelRate, okPercentage.ToString("F3") + "%");
                //         UpdateLabelTextIfChanged(framesTimeForm.ngLabelRate, ngPercentage.ToString("F3") + "%");

                //         // 更新主窗口的标签
                //         UpdateLabelTextIfChanged(sum, totalCount.ToString());
                //         UpdateLabelTextIfChanged(okLabel, localOkCount.ToString());
                //         UpdateLabelTextIfChanged(oksum, okPercentage.ToString("F3") + "%");
                //         UpdateLabelTextIfChanged(nGLabel, localNgCount.ToString());
                //         UpdateLabelTextIfChanged(nGsum, ngPercentage.ToString("F3") + "%");
                //     }));
                //});
                // 确保UI更新发生在主线程
                Invoke(new Action(() =>
                 {
                     // 局部变量，避免多次访问全局变量
                     int localOkCount = okCount;
                     int localNgCount = ngCount;

                     // 计算数据（示例，替换为实际逻辑）
                     double totalCount = localOkCount + localNgCount;
                     //避免无意义的数据刷新
                     if (totalCount == antherCount) return;
                     antherCount = totalCount;
                     double okPercentage = 0;
                     double ngPercentage = 0;

                     try
                     {
                         okPercentage = totalCount == 0 ? 0 : (double)localOkCount / totalCount * 100;
                         ngPercentage = 100 - okPercentage;
                     }
                     catch
                     {
                         if (ngCount != 0)
                         {
                             ngPercentage = 100;
                         }
                     }
                     // 更新所有标签
                     UpdateLabelTextIfChanged(framesTimeForm.sumLabel, totalCount.ToString());
                     UpdateLabelTextIfChanged(framesTimeForm.okLabel, localOkCount.ToString());
                     UpdateLabelTextIfChanged(framesTimeForm.ngLabel, localNgCount.ToString());
                     UpdateLabelTextIfChanged(framesTimeForm.okLabelRate, okPercentage.ToString("F3") + "%");
                     UpdateLabelTextIfChanged(framesTimeForm.ngLabelRate, ngPercentage.ToString("F3") + "%");

                     // 更新主窗口的标签
                     UpdateLabelTextIfChanged(sum, totalCount.ToString());
                     UpdateLabelTextIfChanged(okLabel, localOkCount.ToString());
                     UpdateLabelTextIfChanged(oksum, okPercentage.ToString("F3") + "%");
                     UpdateLabelTextIfChanged(nGLabel, localNgCount.ToString());
                     UpdateLabelTextIfChanged(nGsum, ngPercentage.ToString("F3") + "%");
                 }));
            }
            catch (Exception ex)
            {
                //MessageBox.Show("LabelMessage");
            }
        }
        /// <summary>
        /// 更新label文本值，如果新值与当前值不同，则更新
        /// </summary>
        /// <param name="label">需要更新的label控件</param>
        /// <param name="newText">新的文本值</param>
        public void UpdateLabelTextIfChanged(System.Windows.Forms.Label label, string newText)
        {
            try
            {
                if (label.Text != newText)
                {
                    UpdateLabelText(label, newText);
                }
            }
            catch
            {
                // MessageBox.Show("UpdateLabelTextIfChanged");
            }
        }
        /// <summary>
        /// 更新label
        /// </summary>
        /// <param name="label">需要更新的label控件</param>
        /// <param name="newText">新的文本值</param>
        public void UpdateLabelText(System.Windows.Forms.Label label, string newText)
        {
            try
            {
                if (label.InvokeRequired)
                {
                    label.Invoke(new Action<System.Windows.Forms.Label, string>(UpdateLabelText), label, newText);
                }
                else
                {
                    // 更新label文本值
                    label.Text = newText;
                }
            }
            catch
            {
                //MessageBox.Show("UpdateLabelText");
            }
        }
        #endregion  
        #region 定时垃圾回收
        /// <summary>
        /// 定时启动垃圾回收
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static long lastGcMemory = 0;
        private static long gcThreshold = 1024 * 1024 * 100;  // 150MB 阈值
        private static long gcChangeThreshold = 1024 * 1024 * 20;  // 内存变化阈值，30MB
        private static DateTime lastGcTime = DateTime.MinValue;  // 上次垃圾回收时间
        private static TimeSpan gcCooldownTime = TimeSpan.FromSeconds(10);  // 冷却时间
        private void timer4_Tick(object sender, EventArgs e)
        {
            try
            {
                // 获取当前总内存使用量
                long currentMemory = GC.GetTotalMemory(false);

                // 判断内存使用是否超过了阈值，并且变化量是否超过设定的阈值
                if (currentMemory > gcThreshold && (currentMemory - lastGcMemory) > gcChangeThreshold)
                {
                    // 只有当冷却时间已过，才触发垃圾回收
                    if (DateTime.Now - lastGcTime > gcCooldownTime)
                    {
                        // 执行垃圾回收
                        GC.Collect();
                        lastGcMemory = currentMemory;  // 更新上次垃圾回收时的内存使用量
                        lastGcTime = DateTime.Now;  // 更新回收时间
                    }
                }
            }
            catch (Exception ex)
            {
                // 错误处理，避免未捕获的异常导致程序崩溃
                // MessageBox.Show("timer4_Tick error: " + ex.Message);
            }
        }
        #endregion
        #region 日志方面的代码(写入textbox1与写入日志文件
        // 用于缓存日志内容的队列
        private readonly ConcurrentQueue<string> _logQueue = new ConcurrentQueue<string>();
        private bool _isUpdatingTextBox = false; // 标志位，用于避免多次并发更新 textBox1
        private static ObjectPool<StringBuilder> stringBuilderPool = new ObjectPool<StringBuilder>(100);
        /// <summary>
        /// timer3 - 每1.5秒执行一次，处理队列内容写入 TextBox
        /// </summary>
        private async void timer3_Tick(object sender, EventArgs e)
        {
            if (!runPaper)
            {
                (sender as System.Windows.Forms.Timer).Enabled = false;
                return;
            }

            // 异步处理队列，避免阻塞 UI
            await Task.Run(async () =>
            {
                //Thread.CurrentThread.Priority = ThreadPriority.BelowNormal;
                //await Task.Delay(1);
                try
                {
                    UpdateTextBox();
                    this.Refresh();
                }
                catch
                {
                    //MessageBox.Show("timer3_Tick");
                }
            }).ConfigureAwait(false);
        }
        public void UpdateTextBox()
        {
            try
            {
                List<StringBuilder> newContent = new List<StringBuilder>();
                while (msQueue.TryDequeue(out var item))
                {
                    // 从对象池获取 StringBuilder
                    var sb = stringBuilderPool.Rent();
                    sb.Append(item); // 使用 StringBuilder 进行拼接
                    newContent.Add(sb); // 添加到结果列表
                }

                if (newContent.Count > 0)
                {
                    string newText = string.Join(Environment.NewLine, newContent.Select(sb => sb.ToString()));
                    _logQueue.Enqueue(newText); // 将内容重新放入队列用于 UI 更新

                    // 归还 StringBuilder 到对象池
                    foreach (var sb in newContent)
                    {
                        stringBuilderPool.Return(sb); // 将使用过的 StringBuilder 归还
                    }
                }
                // 更新 UI，避免阻塞
                UpdateTextBoxAsync();
            }
            catch
            {
                //MessageBox.Show("timer3_Tick");
            }
        }
        /// <summary>
        /// 异步更新 TextBox 内容
        /// </summary>
        private async void UpdateTextBoxAsync(bool clearTextBox = false)
        {
            if (_isUpdatingTextBox) return; // 如果已经在更新，则直接返回
            _isUpdatingTextBox = true;

            await Task.Run(() =>
            {
                // Thread.CurrentThread.Priority = ThreadPriority.BelowNormal;
                //await Task.Delay(1).ConfigureAwait;
                (FormDb.Db["Form1"] as Form1)?.Invoke(new Action(() =>
                {
                    try
                    {
                        var form1 = (FormDb.Db["Form1"] as Form1);
                        if (form1?.textBox1 != null)
                        {
                            if (clearTextBox)
                            {
                                form1.textBox1.Clear();
                            }
                            else
                            {
                                while (_logQueue.TryDequeue(out string logItem))
                                {
                                    form1.textBox1.AppendText(logItem + Environment.NewLine);
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        //MessageBox.Show("UpdateTextBoxAsync");
                    }
                    finally
                    {
                        _isUpdatingTextBox = false; // 标志位重置
                    }
                }));
            });
        }

        /// <summary>
        /// 写入日志
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void timer5_Tick(object sender, EventArgs e)
        {
            if (!runPaper)
            {
                (sender as System.Windows.Forms.Timer).Enabled = false;
                return;
            }
            // 异步写入日志文件
            await Task.Run(() =>
            {
                //Thread.CurrentThread.Priority = ThreadPriority.BelowNormal;
                //await Task.Delay(1);
                try
                {
                    // 总路径
                    string station = Path.Combine("Data", "工程文件", this.projectName, $"{this.name}任务文件", "运行结果");

                    string okFilePath = Path.Combine(station, "ok配置.txt");
                    string ngFilePath = Path.Combine(station, "ng配置.txt");
                    File.WriteAllText(ngFilePath, ngCount.ToString());
                    File.WriteAllText(okFilePath, okCount.ToString());

                    // 收集所有日志内容写入文件
                    List<string> logContent = new List<string>();
                    while (_logQueue.TryDequeue(out string logItem))
                    {
                        logContent.Add(logItem);
                    }

                    if (logContent.Count > 0)
                    {
                        Form1.log?.Error(string.Join(Environment.NewLine, logContent));
                    }
                }
                catch (Exception ex)
                {
                    // MessageBox.Show("timer5_Tick");
                }
            }).ConfigureAwait(false);

            // 清空 TextBox 的内容
            UpdateTextBoxAsync(clearTextBox: true);
        }
        #endregion
        #region 将数据同步至csv文件
        /// <summary>
        /// 将数据同步至csv文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void timer1_Tick(object sender, EventArgs e)
        {
            if (!runPaper)
            {
                (sender as System.Windows.Forms.Timer).Enabled = false;
                return;
            }
            // 异步处理队列，避免阻塞 UI
            await Task.Run(async () =>
            {
                //Thread.CurrentThread.Priority = ThreadPriority.BelowNormal;
                //await Task.Delay(1);
                try
                {
                    await csvMainForm.controller.WriteToCsvAsync().ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    MessageBox.Show("csv文件在运行时请勿打开!");
                }

            }).ConfigureAwait(false);


        }
        #endregion
        public void FormClosing()
        {
            try
            {
                List<string> newContent = new List<string>();
                while (msQueue.TryDequeue(out var item))
                {
                    newContent.Add(item);
                }

                if (newContent.Count > 0)
                {
                    string newText = string.Join(Environment.NewLine, newContent);
                    _logQueue.Enqueue(newText); // 将内容重新放入队列用于 UI 更新
                }


                // 总路径
                string station = Path.Combine("Data", "工程文件", this.projectName, $"{this.name}任务文件", "运行结果");
                string okFilePath = Path.Combine(station, "ok配置.txt");
                string ngFilePath = Path.Combine(station, "ng配置.txt");

                File.WriteAllText(okFilePath, okCount.ToString());
                File.WriteAllText(ngFilePath, ngCount.ToString());

                // 收集所有日志内容写入文件
                List<string> logContent = new List<string>();
                while (_logQueue.TryDequeue(out string logItem))
                {
                    logContent.Add(logItem);
                }

                if (logContent.Count > 0)
                {
                    Form1.log?.Error(string.Join(Environment.NewLine, logContent));
                }
            }
            catch (Exception ex)
            {
                //MessageBox.Show("timer5_Tick");
            }
        }
        /// <summary>
        /// 保存csv文件窗体
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripButton5_Click(object sender, EventArgs e)
        {
            try
            {
                csvMainForm.Show();
                csvMainForm.Text = "任务文件_" + this.name + "." + "运行数据";
            }
            catch (Exception ex)
            {
                //MessageBox.Show("toolStripButton5_Click erro");
            }
        }
        /// <summary>
        /// 数据收集
        /// </summary>
        /// <param name="inputArray"></param>
        /// <returns></returns>
        public string ConvertArrayToString<T>(T[] inputArray)
        {
            // 空数组或空引用判断
            if (inputArray == null || inputArray.Length == 0) return "无";

            // 判断输入的数组类型
            if (typeof(T) == typeof(double))
            {
                // 使用 StringBuilder 来拼接字符串，提高效率
                StringBuilder result = stringBuilderPool2.Rent();
                try
                {
                    for (int i = 0; i < inputArray.Length; i++)
                    {
                        result.Append(Math.Round(Convert.ToDouble(inputArray[i]), 3).ToString("F3"));
                        if (i < inputArray.Length - 1) result.Append(",");
                    }
                    return result.ToString();
                }
                finally
                {
                    stringBuilderPool2.Return(result);
                }

            }
            else if (typeof(T) == typeof(bool))
            {
                // 使用 StringBuilder 拼接结果，避免 List 不必要的内存分配
                StringBuilder result = stringBuilderPool2.Rent();
                try
                {
                    bool[] blist = inputArray as bool[]; // 直接转换为 bool[]，若失败则会为 null
                    if (blist == null)
                    {
                        return "无";
                    }

                    for (int i = 0; i < blist.Length; i++)
                    {
                        result.Append(blist[i] ? "合格" : "不合格");
                        if (i < blist.Length - 1) result.Append(",");
                    }
                    return result.ToString();
                }
                finally
                {
                    stringBuilderPool2.Return(result);
                }
            }
            else
            {
                return null; // 非支持的类型返回 null
            }
        }
        /// <summary>
        /// 停止图标
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void toolStripButton6_Click(object sender, EventArgs e)
        {
            try
            {
                this.BeginInvoke(new Action(() => {


                    timer1.Enabled = false;
                    timer2.Enabled = false;
                    timer3.Enabled = false;
                    timer4.Enabled = false;
                    timer5.Enabled = false;
                    this.runPaper = false;
                    this.treeView1.Enabled = true;
                    MessageBox.Show("停止成功 启动请按复位按钮");
                    // 启动闪烁
                    framesTimeForm.indicatorLight1.State = IndicatorLight.IndicatorState.GrayStable; // 切换为灰色   

                })) ;
               
                if (camerFormController != null)
                {
                    //刷新label 刷新日志
                    LabelMessage();
                    UpdateTextBox();

                    await csvMainForm.controller.WriteToCsvAsync(okCount + ngCount).ConfigureAwait(false);
                }
            }
            catch
            {

            }
        }
        /// <summary>
        /// 停止所有工位
        /// </summary>
        public async void Tz()
        {
            try
            {
                this.BeginInvoke((Action)(() =>
                {
                    timer1.Enabled = false;
                    timer2.Enabled = false;
                    timer3.Enabled = false;
                    timer4.Enabled = false;
                    timer5.Enabled = false;
                    this.treeView1.Enabled = true;
                    if (camerFormController != null)
                    {
                        //刷新label 刷新日志
                        LabelMessage();
                        UpdateTextBox();

                    }
                    // 启动闪烁
                    framesTimeForm.indicatorLight1.State = IndicatorLight.IndicatorState.GrayStable; // 切换为灰色   
                }));
                await csvMainForm.controller.WriteToCsvAsync(ngCount + okCount).ConfigureAwait(false);
                ImageCount = okCount + ngCount;
            }
            catch
            {

            }
        }

        /// <summary>
        /// 打开当前存储ng图片的文件夹
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void toolStripButton7_Click(object sender, EventArgs e)
        {
            try
            {
                // ng图片所在的路径
                string ngPath = Path.Combine("Data", "工程文件", this.projectName, $"{this.name}任务文件", "运行结果", "ng图片", DateTime.Now.ToString("yyyy_MM_dd"));

                if (!Directory.Exists(ngPath))
                {
                    Directory.CreateDirectory(ngPath);
                }
                // 获取文件所在的目录
                string directoryPath = System.IO.Path.GetDirectoryName(ngPath + "\\");

                // 打开文件夹资源管理器
                Process.Start("explorer.exe", directoryPath);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"无法打开文件: {ex.Message}");
            }
        }
        /// <summary>
        /// 更改显示模式
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripComboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            toolStripComboBox1.Text = toolStripComboBox1.SelectedItem.ToString();
            //写入文件夹
            string ngCountFilePath = Path.Combine("Data", "工程文件", this.projectName, $"{this.name}任务文件", "运行结果", "显示配置.txt");
            // 读取或创建 OK 文件
            File.WriteAllText(ngCountFilePath, toolStripComboBox1.Text, Encoding.UTF8);
        }

        private void hSmartWindowControl1_HMouseMove(object sender, HMouseEventArgs e)
        {
            try
            {
                x_value.Text = $"X:{(e.X.ToString("F0"))}";
                y_value.Text = $"Y:{e.Y.ToString("F0")}";
                if (hImage != null)
                {
                    //gray_value.Text = "灰度值: " + ((HImage)hImage).Rgb1ToGray().GetGrayval(e.Y, e.X).ToString();
                    HOperatorSet.Rgb1ToGray(hImage, out HObject grayImage);
                    HOperatorSet.GetGrayval(grayImage, e.Y, e.X, out HTuple value);
                    gray_value.Text = "灰度值: " + value;
                }

            }
            catch
            {

            }
        }

        public void RunOpen()
        {
            try
            {
                this.treeView1.Enabled = true;
            }
            catch
            {

            }
        }
        public void RunClose()
        {
            try
            {
                this.treeView1.Enabled = false;
            }
            catch
            {
                this.csvMainForm.toolStripButton1.Click += this.csvMainForm.toolStripButton1_Click;
            }
        }
    }
    public delegate void UpdateLogDelegate();
    public delegate void UpdateTextBoxDelegate(string text);
    /// <summary>
    /// 精准测量模块局部测量数据
    /// </summary>
    public class HardRunLineData
    {
        //卡尺工具数据
        public double[,] linesList;
        public double[] HideOutputArrayDistancesCailper;
        public double[] HideOutputArrayRowsCailper;
        public double[] HideOutputArrayColumnsCailper;
        //距离转换数据
        public double[] HideOutputArrayDistancesDistance;
        //结果分析数据
        public bool[] HideOutputResultsAna;
        //间距最终数据
        public List<bool> HideOutputResults间距;


    }

    public class ObjectPool<T> where T : class, new()
    {
        private readonly ConcurrentBag<T> _pool;

        private readonly int _maxPoolSize;

        public ObjectPool(int maxPoolSize = 50)
        {
            _pool = new ConcurrentBag<T>()
            {
            };
            _maxPoolSize = maxPoolSize;
        }

        // 获取对象
        public T Rent()
        {
            // 如果池中有对象，直接返回
            if (_pool.TryTake(out var item))
            {
                return item;
            }
            // 如果池为空，创建新对象
            return new T();
        }
        // 归还对象
        public void Return(T item)
        {
            if (item == null) return;
            // 清理对象的数据
            ClearItemData(item);

            // 如果池未超出容量，将对象放回池中
            if (_pool.Count < _maxPoolSize)
            {
                _pool.Add(item);
            }
            else if (item is HSmartWindowControl hSmart && !_pool.Any(obj => ReferenceEquals(obj, hSmart)))
            {
                hSmart?.HalconWindow?.CloseWindow();
                hSmart?.Dispose();
            }
            // 如果超出容量，丢弃对象（让 GC 回收）
            item = null;
        }

        // 清理对象的数据
        private void ClearItemData(T item)
        {
            if (item is StringBuilder sb)
            {
                sb.Clear();
            }
            else if (item is Dictionary<bool[], string> list)
            {
                list.Clear();
            }
            else if (item is List<Task> dictionary)
            {
                // dictionary.Clear();
            }
            else if (item is HSmartWindowControl hsmart)
            {
                // hsmart.HalconWindow.ClearWindow();
            }
            else if (item is ConcurrentDictionary<int, HardRunLineData> hList)
            {
                foreach (var kv in hList)
                {
                    kv.Value.linesList = null;
                    kv.Value.HideOutputResults间距 = null;
                    kv.Value.HideOutputResultsAna = null;
                    kv.Value.HideOutputArrayColumnsCailper = null;
                    kv.Value.HideOutputArrayDistancesCailper = null;
                    kv.Value.HideOutputArrayRowsCailper = null;
                    kv.Value.HideOutputArrayDistancesDistance = null;
                }
                hList.Clear();
            }
            else if (item is Stopwatch stop)
            {
                stop.Reset();
            }
            else if (item is ConcurrentDictionary<List<bool>, string> ss)
            {
                ss.Clear();
            }
            // 添加其他类型的数据清理逻辑
        }
    }
}
